import AppSettings from "@runtime/base/AppSettings";
import { ClientMessage } from "@runtime/generate/message/ClientMessage";
import DeviceComponent from "@runtime/module/Device/DeviceComponent";
import ModalComponent, { ModalOptions } from "@runtime/module/Modal/ModalComponent";
import RouterComponent from "@runtime/module/Router/RouterComponent";
import TimerComponent from "@runtime/module/Timer/TimerComponent";
import WebSocketComponent from "@runtime/module/WebSocket/WebSocketComponent";
import WebWindowComponent from "@runtime/module/WebWindow/WebWindowComponent";
import AnimatorComponent from "@runtime/UnityEngineBridge/AnimatorComponent";
import AssetLoaderComponent from "@runtime/UnityEngineBridge/AssetLoaderComponent";
import GameObjectComponent from "@runtime/UnityEngineBridge/GameObjectComponent";
import HighlighterComponent from "@runtime/UnityEngineBridge/HighlighterComponent";
import InteractableObjectComponent from "@runtime/UnityEngineBridge/InteractableObjectComponent";
import LabelComponent from "@runtime/UnityEngineBridge/LabelComponent";
import PostProcessLayerComponent from "@runtime/UnityEngineBridge/PostProcessLayerComponent";
import TooltipComponent from "@runtime/UnityEngineBridge/TooltipComponent";
import { computed, ComputedRef, reactive, ref, Ref, UnwrapNestedRefs, watch, WatchStopHandle } from "vue";
import LidarSettings from "./LidarSettings";
import OrbitCameraComponent from "./OrbitCameraComponent";
import RoomComponent from "./RoomComponent";
import UsageCameraComponent from "./UsageCameraComponent";

function ToMap<TKey, TValue>(sources: Array<TValue>, keySelector: (element: TValue) => TKey): Map<TKey, TValue> {
    const map = new Map<TKey, TValue>();
    for (const element of sources) {
        map.set(keySelector(element), element);
    }
    return map;
}

export const ModuleConfigs: ComputedRef<Array<{ Id: number, Name: string, Description: string, Icon: string }>> = computed(() => {
    const configs = [
        { Id: 1, Name: 'Introduction', Description: '系统简介', Icon: 'ic_menu_1' },
        { Id: 2, Name: 'Structure', Description: '结构认知', Icon: 'ic_menu_2' },
        { Id: 3, Name: 'Principle', Description: '工作原理', Icon: 'ic_menu_3' },
        { Id: 4, Name: 'Install', Description: '安装', Icon: 'ic_menu_4' },
        { Id: 5, Name: 'Calibration', Description: '标定', Icon: 'ic_menu_5' },
        { Id: 6, Name: 'Protocol', Description: '协议解读', Icon: 'ic_menu_6' },
        { Id: 7, Name: 'Usage', Description: '应用', Icon: 'ic_menu_7' },
    ];

    // if (LidarComponent.Default.Status.value == '设备已连接') {
    //     configs.add({ Id: 7, Name: 'Usage', Description: '应用', Icon: 'ic_menu_7' },);
    // }

    return configs;
});

class CoroutineLock implements Chaos.IDisposable {
    public Type: number = 0;
    public Key: number = 0;
    public Count: number = 0;

    private isCompleted: boolean = false;
    private task?: (value: void | PromiseLike<void>) => void;

    constructor(type: number, key: number, count: number) {
        this.Type = type;
        this.Key = key;
        this.Count = count;
    }

    async WaitAsync(): Promise<void> {
        if (this.isCompleted) {
            return;
        }

        return new Promise(resolve => this.task = resolve);
    }

    Dispose() {
        LidarComponent.Default.IsLoading.value = false;

        this.Type = 0;
        this.Key = 0;
        this.Count = 0;

        if (this.task != undefined) {
            this.task();
        }

        this.isCompleted = true;
    }
}

/**
 * 毫米波雷达组件
 */
export default class LidarComponent {
    private static instance: LidarComponent = new LidarComponent();
    /**
     * 毫米波雷达组件
     */
    public static get Default(): LidarComponent {
        return this.instance;
    }

    constructor() {
        window.addEventListener('unload', this.Dispose.bind(this));

        this.watchStopHandles.push(watch(this.Status, this.OnDeviceUpdatedAsync.bind(this)));
        this.watchStopHandles.push(watch(this.Module, this.OnModuleChangedAsync.bind(this)));
    }

    Dispose() {
        window.removeEventListener('unload', this.Dispose);

        for (const watchStopHandle of this.watchStopHandles) {
            watchStopHandle();
        }
        this.watchStopHandles.clear();
    }

    public DeviceId: number = 0;

    public connect: Ref<string> = ref('');
    // public Status: ComputedRef<string> = computed(() => DeviceComponent.Default.Devices.get(this.DeviceId)?.Status ?? '设备连接中');
    public Status: ComputedRef<string> = computed(() => DeviceComponent.Default.Devices.get(this.DeviceId)?.Status ?? this.connect.value);

    public IsLoading: Ref<boolean> = ref(false);

    public Module: Ref<string> = ref('');

    private map: Map<number, Array<CoroutineLock>> = new Map();

    private hasInitialized: boolean = false;

    private watchStopHandles: Array<WatchStopHandle> = [];

    public async Awake(): Promise<void> {
        ModalComponent.Default.AddDynamicModules(import.meta.glob('/src/components/Apps/Lidar/Exit.vue'));
        ModalComponent.Default.AddDynamicModules(import.meta.glob('/src/components/Apps/Lidar/MessageBox.vue'));

        this.Module.value = 'Home';

        // 启动Unity
        const configuration = JSON.stringify({
            LocalAddress: AppSettings.Default.LocalAddress,
            ShortName: 'P10082',
            Type: 6,
        });
        await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.EmbeddedApplicationLaunchRequest('../EmbeddedApplication/Unity/Mix.Unity.exe', configuration));

        // 获取Unity版本状态
        await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.EmbeddedApplicationVersionRequest());

        // if (!this.hasInitialized) {
        //     await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.MillimeterWaveRadarDeviceInitializationRequest(
        //         LidarSettings.Default.DeviceType,
        //         LidarSettings.Default.DeviceIndex,
        //         LidarSettings.Default.CanIndex,
        //     ));

        //     this.hasInitialized = true;
        // }

        this.Module.value = 'Introduction';
    }

    public async Destroy(): Promise<void> {
    }

    private async OnDeviceUpdatedAsync(current: string, previous: string): Promise<void> {
        const lock = await LidarComponent.Default.WaitAsync();

        const modules = ModuleConfigs.value.map(config => config.Name);
        if (this.Status.value != '设备连接成功' && !modules.includes(this.Module.value)) {
            this.Module.value = modules[0];
        }

        lock.Dispose();
    }

    /**
    * 模块发生变化时
    * @param value 模块
    */
    private async OnModuleChangedAsync(value: string): Promise<void> {
        // 切换至指定传感器路由
        const url = `/${AppSettings.Default.Type}/${value}`;
        await RouterComponent.Default.NavigateToAsync(url);
    }

    public async OnExitAsync(): Promise<void> {
        const volume = await PostProcessLayerComponent.Default.AddVolumeAsync();
        const effect = await PostProcessLayerComponent.Default.AddKawaseBlurAsync(volume);

        const options = ModalOptions.Default()
            .WithPrefix('/src/components/Apps/Lidar/')
            .WithType('Exit')
            .WithContent('是否确认退出软件?')
            .WithButtons(['确定', '取消']);
        const result = await ModalComponent.Default.PopupAsync(options);

        if (result == '确定') {
            WebSocketComponent.Default.PostMessage(new ClientMessage.ShutdownMessage());
        }

        await PostProcessLayerComponent.Default.RemoveEffectAsync(volume, effect);
        await PostProcessLayerComponent.Default.RemoveVolumeAsync(volume);
    }

    public async WaitAsync(type: number = 0, key: number = 0): Promise<CoroutineLock> {
        this.IsLoading.value = true;

        if (!this.map.has(key)) {
            this.map.set(key, []);
        }

        const locks = this.map.get(key)!;
        const lock = new CoroutineLock(type, key, locks.length);
        locks.add(lock);
        if (locks.length < 2) {
            return new Promise(resolve => resolve(lock));
        } else {
            const previous = locks[locks.length - 2];
            await previous.WaitAsync();
            return new Promise(resolve => resolve(lock));
        }
    }
}

/**
 * 简介
 */
export class IntroductionComponent {
    private static instance: IntroductionComponent = new IntroductionComponent();
    /**
     * 简介
     */
    public static get Default(): IntroductionComponent {
        return this.instance;
    }

    constructor() {
        window.addEventListener('unload', this.Dispose.bind(this));
    }

    Dispose() {
        window.removeEventListener('unload', this.Dispose);

        for (const watchStopHandle of this.watchStopHandles) {
            watchStopHandle();
        }
        this.watchStopHandles.clear();
    }

    public Title: string = '激光雷达系统';

    public Description: string = `激光雷达（英文：Laser Radar [1]  ），是以发射激光束探测目标的位置、速度等特征量的雷达系统。其工作原理是向目标发射探测信号（激光束），然后将接收到的从目标反射回来的信号（目标回波）与发射信号进行比较，作适当处理后，就可获得目标的有关信息，如目标距离、方位、高度、速度、姿态、甚至形状等参数，从而对飞机、导弹等目标进行探测、跟踪和识别。它由激光发射机、光学接收机、转台和信息处理系统等组成，激光器将电脉冲变成光脉冲发射出去，光接收机再把从目标反射回来的光脉冲还原成电脉冲，送到显示器。
`;

    public Img: string = '/static/LaserRadar/激光雷达简介.png';

    private instanceId: number = 0;

    private watchStopHandles: Array<WatchStopHandle> = [];

    public async Awake(): Promise<void> {
        const lock = await LidarComponent.Default.WaitAsync();

        WebWindowComponent.Default.SetTransparentBackground();
        TooltipComponent.Default.Clear();

        if (this.instanceId == 0) {
            this.instanceId = await AssetLoaderComponent.Default.LoadAsync('Assets/R00062/ICV/Res/Product/Introduction/激光雷达系统/新石器激光雷达系统.prefab');
        } else {
            await GameObjectComponent.Default.ShowAsync(this.instanceId);
        }

        await OrbitCameraComponent.Default.UpdateAsync([-0.9, 0.18, 0.03], 25, 26, 6, 0.1, 10);

        lock.Dispose();
    }

    public async Destroy(): Promise<void> {
        const lock = await LidarComponent.Default.WaitAsync();

        await GameObjectComponent.Default.HideAsync(this.instanceId);

        lock.Dispose();
    }
}

class StructureOptionConfig {
    Id: number;
    InstanceId: number;
    Type: string;
    Asset: string;
    /**
     * 动画状态
     */
    State: string;
    Description: string;
    ViewId: number;

    constructor(id: number, instanceId: number, type: string, asset: string, state: string, description: string, viewId: number) {
        this.Id = id;
        this.InstanceId = instanceId;
        this.Type = type;
        this.Asset = asset;
        this.State = state;
        this.Description = description;
        this.ViewId = viewId;
    }
}

class StructureConfig {
    Id: number;
    Name: string;
    Options: Array<number>;

    constructor(id: number, name: string, options: Array<number>) {
        this.Id = id;
        this.Name = name;
        this.Options = options;
    }
}

class TreeNode {
    public Id: number;
    public Parent: TreeNode | undefined;
    public Children: Array<TreeNode>;

    public Expand: boolean;

    public get HasChildren(): boolean {
        return this.Children.length != 0;
    }


    public get Indent(): number {
        return (this.Parent?.Indent ?? -1) + 1;
    }


    constructor(id: number, children: Array<TreeNode> = [], expand: boolean = false, parent: TreeNode | undefined = undefined) {
        this.Id = id;
        this.Parent = parent;
        this.Children = children;
        this.Expand = expand;

        for (const child of this.Children) {
            child.Parent = this;
        }
    }
}

/**
 * 结构认知
 */
export class StructureComponent {
    private static instance: StructureComponent = new StructureComponent();
    /**
     * 结构认知
     */
    public static get Default(): StructureComponent {
        return this.instance;
    }

    constructor() {
        window.addEventListener('unload', this.Dispose.bind(this));

        this.watchStopHandles.push(watch(this.Id, this.OnIdChangedAsync.bind(this)));
        this.watchStopHandles.push(watch(this.OptionId, this.OnOptionIdChangedAsync.bind(this)));
    }

    Dispose() {
        window.removeEventListener('unload', this.Dispose);

        for (const watchStopHandle of this.watchStopHandles) {
            watchStopHandle();
        }
        this.watchStopHandles.clear();
    }

    public Node: UnwrapNestedRefs<TreeNode> = reactive(new TreeNode(1, [
        new TreeNode(2,[
            new TreeNode(15),
            new TreeNode(16),
            new TreeNode(17),
            new TreeNode(18),
            new TreeNode(19),
            new TreeNode(20),
            new TreeNode(21),
            new TreeNode(22),  
            new TreeNode(23),  
            new TreeNode(24),  
            new TreeNode(25),  
        ]),
        new TreeNode(3),
        new TreeNode(4),
        new TreeNode(5),
        new TreeNode(6),
        new TreeNode(7),
        new TreeNode(8),
        new TreeNode(9),
        new TreeNode(10),
        new TreeNode(11),
        new TreeNode(12),
        new TreeNode(13),
        new TreeNode(14),
    ], true));

    /**
     * 结构配置
     */
    public Configs: UnwrapNestedRefs<Map<number, StructureConfig>> = reactive(ToMap<number, StructureConfig>([
        new StructureConfig(1, '激光雷达系统', [1, 2]),
        new StructureConfig(2, '激光雷达', [3, 4]),

        new StructureConfig(15, '主控及处理电路板', [17]),
        new StructureConfig(16, '光学系统', [18]),
        new StructureConfig(17, '激光雷达底座', [19]),
        new StructureConfig(18, '激光雷达发射器', [20]),
        new StructureConfig(19, '激光雷达接收器', [21]),
        new StructureConfig(20, '电机控制器', [22]),
        new StructureConfig(21, '轴承', [23]),
        new StructureConfig(22, '壳体', [24]),
        new StructureConfig(23, '激光雷达上盖', [25]),
        new StructureConfig(24, '激光雷达密封圈', [26]),
        new StructureConfig(25, '电机', [27]),

        new StructureConfig(3, '交换机', [5]),
        new StructureConfig(4, '交换机电源组合线束', [6]),  
        new StructureConfig(5, '交换机至计算机网线', [7]), 
        new StructureConfig(6, '低压蓄电池', [8]),
        new StructureConfig(7, '保险丝盒', [9]),
        new StructureConfig(8, '电源总开关', [10]),
        new StructureConfig(9, '计算单元', [11]),
        new StructureConfig(10, '计算单元电源正极线束', [12]),
        new StructureConfig(11, '计算单元电源负极线束', [13]),
        new StructureConfig(12, '保险丝盒电源正级线束', [14]),
        new StructureConfig(13, '电源总开关负极线束', [15]),
        new StructureConfig(14, '电源总开关负极线束接搭铁', [16]),


    ], element => element.Id));

    public Options: UnwrapNestedRefs<Map<number, StructureOptionConfig>> = reactive(ToMap<number, StructureOptionConfig>([
        new StructureOptionConfig(1, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/新石器激光雷达系统组成.prefab', '', '', 3001),
        new StructureOptionConfig(2, 0, '组成', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/新石器激光雷达系统组成.prefab', '', '', 3002),
        
        new StructureOptionConfig(3, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/激光雷达.prefab', '', '', 3003),
        new StructureOptionConfig(4, 0, '组成', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/激光雷达.prefab', 'Default', '', 3004),
        
        new StructureOptionConfig(5, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/交换机.prefab', '', '', 3041),
        
        new StructureOptionConfig(6, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/交换机电源组合线束.prefab', '', '', 3049),
        
        new StructureOptionConfig(7, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/交换机至计算机网线.prefab', '', '', 3007),
        
        new StructureOptionConfig(8, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/低压蓄电池.prefab', '', '', 3025),
        
        new StructureOptionConfig(9, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/保险丝盒.prefab', '', '', 3027),
        
        new StructureOptionConfig(10, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/电源总开关.prefab', '', '', 3043),
        
        new StructureOptionConfig(11, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/计算单元.prefab', '', '', 3005),
        
        new StructureOptionConfig(12, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/计算单元电源正极线束.prefab', '', '', 3009),
        
        new StructureOptionConfig(13, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/计算单元电源负极线束.prefab', '', '', 3011),
        
        new StructureOptionConfig(14, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/保险丝盒电源正级线束.prefab', '', '', 3029),
        
        new StructureOptionConfig(15, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/电源总开关负极线束.prefab', '', '', 3046),
        
        new StructureOptionConfig(16, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/电源总开关负极线束接搭铁.prefab', '', '', 3047),

        new StructureOptionConfig(17, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/主控及处理电路板.prefab', '', '', 3014),
        new StructureOptionConfig(18, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/光学系统.prefab', '', '', 3018),
        new StructureOptionConfig(19, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/激光雷达底座.prefab', '', '', 3023),
        new StructureOptionConfig(20, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/激光雷达发射器.prefab', '', '', 3016),
        new StructureOptionConfig(21, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/激光雷达接收器.prefab', '', '', 3017),
        new StructureOptionConfig(22, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/电机控制器.prefab', '', '', 3021),
        new StructureOptionConfig(23, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/轴承.prefab', '', '', 3015),
        new StructureOptionConfig(24, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/壳体.prefab', '', '', 3019),
        new StructureOptionConfig(25, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/激光雷达上盖.prefab', '', '', 3013),
        new StructureOptionConfig(26, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/激光雷达密封圈.prefab', '', '', 3022),
        new StructureOptionConfig(27, 0, '结构', 'Assets/R00062/ICV/Res/Product/Structure/新石器激光雷达系统/电机.prefab', '', '', 3020),

    ], element => element.Id));

    /**
     * 当前结构配置Id
     */
    public Id: Ref<number> = ref(1);

    /**
     * 当前结构配置选项Id
     */
    public OptionId: Ref<number> = ref(1);

    /**
     * 当前结构配置
     */
    public Config: ComputedRef<StructureConfig> = computed(() => this.Configs.get(this.Id.value)!);

    /**
     * 当前结构配置
     */
    public Option: ComputedRef<StructureOptionConfig> = computed(() => this.Options.get(this.OptionId.value)!);

    public FilterOptions: ComputedRef<Array<StructureOptionConfig>> = computed(() => Array.from(this.Options.values()).filter(config => this.Config.value.Options.includes(config.Id)));

    /**
     * 当前选项对应文本描述
     */
    public Description: ComputedRef<string> = computed(() => this.Options.get(this.OptionId.value)?.Description ?? '');
    public DescriptionAudioAccessibility: Ref<boolean> = ref(true);
    public AudioStats = reactive({ pausable: false });

    private hasInitialized: boolean = false;
    private watchStopHandles: Array<WatchStopHandle> = [];

    public async Awake(): Promise<void> {
        const lock = await LidarComponent.Default.WaitAsync();

        WebWindowComponent.Default.SetTransparentBackground();
        TooltipComponent.Default.Clear();

        if (!this.hasInitialized) {
            await this.LoadAsync();
            this.hasInitialized = true;
        } 
        // else {
        //     await GameObjectComponent.Default.ShowAsync(this.Option.value.InstanceId);
        // }

        await GameObjectComponent.Default.ShowAsync(this.Option.value.InstanceId);
        await OrbitCameraComponent.Default.ApplyConfigAsync(this.Option.value.ViewId);
        if (this.Option.value.Type == '组成') {
            // 加载标签
            await LabelComponent.Default.LoadAsync(this.Option.value.InstanceId);
        }

        lock.Dispose();
    }

    public async Destroy(): Promise<void> {
        const lock = await LidarComponent.Default.WaitAsync();

        LabelComponent.Default.Clear();
        await HighlighterComponent.Default.ClearAsync();

        await GameObjectComponent.Default.HideAsync(this.Option.value.InstanceId);

        lock.Dispose()
    }

    private async LoadAsync(): Promise<void> {
        this.Option.value.InstanceId = await AssetLoaderComponent.Default.LoadAsync(this.Option.value.Asset);
    }



    private FindNode(id: number): TreeNode | undefined {
        let node: TreeNode | undefined;

        function Find(id: number, input: TreeNode): void {
            if (input.Id == id) {
                node = input;
                return;
            }

            for (const child of input.Children) {
                Find(id, child);
            }
        }

        Find(id, this.Node);

        return node;
    }

    /**
     * 判断当年前节点是否有子节点
     * @param id 当前节点Id
     * @returns 是否有子节点
     */
    public HasChildren(id: number): boolean {
      return this.FindNode(id)?.HasChildren ?? false;
    }

    /**
     * 计算当前节点缩进级别
     * @param id 当前节点Id
     * @returns 当前节点缩进级别
     */
    public CalculateIndent(id: number): number {
        return this.FindNode(id)?.Indent ?? 0;
    }
    public CanShowNode(id: number): boolean {
        let node = this.FindNode(id)!;
        while (node.Parent != undefined) {
            if (!node.Parent.Expand) {
                return false;
            } else {
                node = node.Parent;
            }
        }
        return true;
    }

    public IsNodeExpand(id: number): boolean {
        return this.FindNode(id)?.Expand ?? false;
    }

    public SwitchNodeExpand(id: number): void {
        let node = this.FindNode(id)!;
        node.Expand = !node.Expand;
    }


    /**
     * Id发生变化时
     */
    private async OnIdChangedAsync(): Promise<void> {
        this.OptionId.value = this.Config.value.Options[0];
    }
    /**
     * 选项发生变化时
     * @param current 当前值
     * @param previous 过去值
     */
    private async OnOptionIdChangedAsync(current: number, previous: number): Promise<void> {
        LidarComponent.Default.IsLoading.value = true;

        if (import.meta.env.PROD) {
            await GameObjectComponent.Default.HideAsync(this.Options.get(previous)!.InstanceId);

            // 清空标签
            LabelComponent.Default.Clear();
            // 重置高亮
            await HighlighterComponent.Default.ClearAsync();

            if (this.Option.value.InstanceId == 0) {
                const volume = await PostProcessLayerComponent.Default.AddVolumeAsync();
                const effect = await PostProcessLayerComponent.Default.AddKawaseBlurAsync(volume);

                // 加载模型
                this.Option.value.InstanceId = await AssetLoaderComponent.Default.LoadAsync(this.Option.value.Asset);

                await PostProcessLayerComponent.Default.RemoveEffectAsync(volume, effect);
                await PostProcessLayerComponent.Default.RemoveVolumeAsync(volume);
            }

            // 显示当前选项模型
            await GameObjectComponent.Default.ShowAsync(this.Option.value.InstanceId);

            // 切换视角
            await OrbitCameraComponent.Default.ApplyConfigAsync(this.Option.value.ViewId);

            if (this.Option.value.State != '') {
                // 播放动画
                await AnimatorComponent.Default.PlayAsync(this.Option.value.InstanceId, this.Option.value.State, 1000);
            }

            if (this.Option.value.Type == '组成') {
                // 加载标签
                await LabelComponent.Default.LoadAsync(this.Option.value.InstanceId);
            }
        }

        LidarComponent.Default.IsLoading.value = false;
    }
}

class PrincipleConfig {
    Id: number;
    InstanceId: number;
    Name: string;
    Asset: string;
    /**
     * 动画状态
     */
    State: string;
    Description: string;
    ViewId: number;

    constructor(id: number, instanceId: number, name: string, asset: string, state: string, description: string, viewId: number) {
        this.Id = id;
        this.InstanceId = instanceId;
        this.Name = name;
        this.Asset = asset;
        this.State = state;
        this.Description = description;
        this.ViewId = viewId;
    }
}

/**
 * 工作原理
 */
export class PrincipleComponent {
    private static instance: PrincipleComponent = new PrincipleComponent();
    /**
     * 工作原理
     */
    public static get Default(): PrincipleComponent {
        return this.instance;
    }

    constructor() {
        window.addEventListener('unload', this.Dispose.bind(this));

        this.watchStopHandles.push(watch(this.Id, this.OnIdChangedAsync.bind(this)));
    }

    Dispose() {
        window.removeEventListener('unload', this.Dispose);

        for (const watchStopHandle of this.watchStopHandles) {
            watchStopHandle();
        }
        this.watchStopHandles.clear();
    }

    /**
    * 当前原理配置
    */
    public Configs: UnwrapNestedRefs<Array<PrincipleConfig>> = reactive([
        new PrincipleConfig(
            1,
            0,
            '激光雷达工作原理',
            'Assets/R00062/ICV/Res/Product/Principle/激光雷达系统/激光雷达工作原理.prefab',
            '',
            '激光雷达的工作原理是16线机械式激光雷达内有16组激光发射器和激光接收器，以每隔大约2°的角度布置在激光内部转子上，发射激光时，从下至上，每隔2.8微秒发射一次激光，16组激光发射完成后，激光雷达转子就旋转一定角度，然后再依次发射16组激光，激光雷达每分钟以300-1200转的速度旋转，根据激光测距原理，就可以在空间中形成点云。',
            3031),
        new PrincipleConfig(
            2,
            0,
            '激光雷达测距原理',
            'Assets/R00062/ICV/Res/Product/Principle/激光雷达系统/激光雷达测距原理.prefab',
            '',
            '激光雷达的测距原理是由激光发射器以一个很小的角度发射激光，激光遇到障碍物，反射回来，被激光接收器接收，从发射到接收的时间t内，激光移动了2d距离，光在地球上的移动速度是大约是三亿米每秒，光速乘以发射到接收的时间t，就是激光移动的距离，移动距离的一半就是雷达到障碍物的距离，这就是激光测距的原理。',
            3032),
    ]);

    /**
     * 当前原理配置Id
     */
    public Id: Ref<number> = ref(0);

    public Description: Ref<string> = ref('');
    public DescriptionAudioAccessibility: Ref<boolean> = ref(true);
    public AudioStats = reactive({ pausable: false });

    private watchStopHandles: Array<WatchStopHandle> = [];

    private instanceIds: Array<number> = [];

    public async Awake(): Promise<void> {
        const lock = await LidarComponent.Default.WaitAsync();

        WebWindowComponent.Default.SetTransparentBackground();
        TooltipComponent.Default.Clear();

        if (this.instanceIds.length == 0) {
            await this.LoadAsync(this.Configs.map(config => config.Asset));
            this.Id.value = this.Configs[0].Id;
        } 
        // else {
        //     const config = this.Configs.find(config => config.Id == this.Id.value)!;
        //     await GameObjectComponent.Default.ShowAsync(config.InstanceId);
        //     await OrbitCameraComponent.Default.ApplyConfigAsync(config.ViewId);
        // }
        const config = this.Configs.find(config => config.Id == this.Id.value)!;
        await GameObjectComponent.Default.ShowAsync(config.InstanceId);
        await OrbitCameraComponent.Default.ApplyConfigAsync(config.ViewId);
        

        //lock.Dispose();
        lock.Dispose();
    }

    public async Destroy(): Promise<void> {
        const lock = await LidarComponent.Default.WaitAsync();
        await GameObjectComponent.Default.HideAsync(this.instanceIds);
        //lock.Dispose();
        lock.Dispose();
    }

    private async LoadAsync(assets: Array<string>): Promise<void> {
        if (import.meta.env.DEV) {
            return;
        }

        const volume = await PostProcessLayerComponent.Default.AddVolumeAsync();
        const effect = await PostProcessLayerComponent.Default.AddKawaseBlurAsync(volume);

        this.instanceIds.clear();
        this.instanceIds.addRange(await AssetLoaderComponent.Default.LoadAllAsync(assets));

        await PostProcessLayerComponent.Default.RemoveEffectAsync(volume, effect);
        await PostProcessLayerComponent.Default.RemoveVolumeAsync(volume);

        for (let index = 0; index < this.instanceIds.length; ++index) {
            const instanceId = this.instanceIds[index];
            this.Configs[index].InstanceId = instanceId;
        }

        await GameObjectComponent.Default.HideAsync(this.instanceIds);
    }

    /**
     * 原理Id发生变化时
     * @param value 值
     */
    private async OnIdChangedAsync(value: number, previous: number): Promise<void> {
        // 更新结构数据
        const config = this.Configs.find(config => config.Id == value)!;
        await GameObjectComponent.Default.ShowAsync(config.InstanceId);
        await OrbitCameraComponent.Default.ApplyConfigAsync(config.ViewId);

        const previousConfig = this.Configs.find(config => config.Id == previous);
        if (import.meta.env.PROD) {
            if (config != null) {
                if (previousConfig != null) {
                    await GameObjectComponent.Default.HideAsync(previousConfig.InstanceId);
                }

                await GameObjectComponent.Default.ShowAsync(config.InstanceId);
            } else {
                window.Logger.Error(`对应选项(Id:${value})不存在`);
            }
        }

        this.Description.value = config?.Description ?? '';
    }
}

class InstallStepConfig {
    Id: number;
    Name: string;
    Asset: string;

    constructor(id: number, name: string, asset: string) {
        this.Id = id;
        this.Name = name;
        this.Asset = asset;
    }
}

class InstallViewConfig {
    Id: number;
    Name: string;
    Icon: string;

    constructor(id: number, name: string, icon: string) {
        this.Id = id;
        this.Name = name;
        this.Icon = icon;
    }
}

/**
 * 安装组件
 */
export class InstallComponent {
    private static instance: InstallComponent = new InstallComponent();
    /**
     * 安装组件
     */
    public static get Default(): InstallComponent {
        return this.instance;
    }

    constructor() {
        window.addEventListener('unload', this.Dispose.bind(this));

        this.watchStopHandles.push(watch(this.ViewId, this.OnViewChangedAsync.bind(this)));
    }

    Dispose() {
        window.removeEventListener('unload', this.Dispose);

        for (const watchStopHandle of this.watchStopHandles) {
            watchStopHandle();
        }
        this.watchStopHandles.clear();
    }

    public currentPartName = ref()
    public StepDescriptions = ref<any>([
        {name:'1.安装低压蓄电池',type:false},
        {name:'2.安装保险丝盒',type:false},
        {name:'3.安装保险丝盒电源正级线束',type:false},
        {name:'4.安装电源总开关',type:false},
        {name:'5.安装电源总开关负极线束接搭铁',type:false},
        {name:'6.安装电源总开关负极线束',type:false},
        {name:'7.安装计算单元',type:false},
        {name:'8.安装计算单元电源负极线束',type:false},
        {name:'9.安装计算单元电源正极线束',type:false},
        {name:'10.安装交换机',type:false},
        {name:'11.安装交换机电源组合线束',type:false},
        {name:'12.安装交换机至计算机网线',type:false},
        {name:'13.安装激光雷达',type:false},
    ]);

    /**
     * 步骤提示
     */
    public StepTips: Array<InstallStepConfig> = [
        new InstallStepConfig(1, '步骤一', 'Step001.png'),
        new InstallStepConfig(2, '步骤二', 'Step002.png'),
        new InstallStepConfig(3, '步骤三', 'Step003.png'),
        new InstallStepConfig(4, '步骤四', 'Step004.png'),
        new InstallStepConfig(4, '步骤五', 'Step005.png'),
        new InstallStepConfig(4, '步骤六', 'Step006.png'),
    ];

    /**
     * 视角配置
     */
    public Views: Array<InstallViewConfig> = [
        new InstallViewConfig(3034, '目标', 'ic_mubiao'),
        new InstallViewConfig(3035, '零件桌1', 'ic_lingjianzhuo'),
        new InstallViewConfig(3036, '零件桌2', 'ic_lingjianzhuo'),
        new InstallViewConfig(3037, '零件桌3', 'ic_lingjianzhuo'),
        new InstallViewConfig(3051, '车顶', 'ic_cheding'),
        new InstallViewConfig(3052, '车前', 'ic_cheqian'),
    ];

    public CanRecyclePart: ComputedRef<boolean> = computed(() => this.ViewId.value == 3035);

    public ViewId: Ref<number> = ref(0);

    public StepState: Ref<boolean> = ref(false);

    private watchStopHandles: Array<WatchStopHandle> = [];

    private instanceIds: Array<number> = [];

    public async Awake(): Promise<void> {
        const lock = await LidarComponent.Default.WaitAsync();

        WebWindowComponent.Default.SetTransparentBackground();
        TooltipComponent.Default.Clear();

        await RoomComponent.Default.ShowAsync();

        if (import.meta.env.PROD) {
            if (this.instanceIds.length == 0) {
                await this.LoadAsync([
                    'Assets/R00062/ICV/Res/Product/DisassemblyAndAssembly/零件桌/零件桌模块.prefab',
                    'Assets/R00062/ICV/Res/Product/DisassemblyAndAssembly/激光雷达系统安装/新石器激光雷达安装.prefab'
                ]);
            } else {
                await GameObjectComponent.Default.ShowAsync(this.instanceIds);
            }
        }

        this.ViewId.value = this.Views[0].Id;
        await OrbitCameraComponent.Default.ApplyConfigAsync(this.ViewId.value);

        lock.Dispose();
    }

    public async Destroy(): Promise<void> {
        const lock = await LidarComponent.Default.WaitAsync();

        this.StepState.value = false;

        await GameObjectComponent.Default.HideAsync(this.instanceIds);

        await RoomComponent.Default.HideAsync();

        lock.Dispose();
    }

    private async LoadAsync(assets: Array<string>): Promise<void> {
        const volume = await PostProcessLayerComponent.Default.AddVolumeAsync();
        const effect = await PostProcessLayerComponent.Default.AddKawaseBlurAsync(volume);

        this.instanceIds.clear();
        this.instanceIds.addRange(await AssetLoaderComponent.Default.LoadAllAsync(assets));

        await PostProcessLayerComponent.Default.RemoveEffectAsync(volume, effect);
        await PostProcessLayerComponent.Default.RemoveVolumeAsync(volume);

        await InteractableObjectComponent.Default.LoadAsync(['LaserRadar', 'LaserRadarLocation']);
    }

    /**
     * 安装视角发生变化
     * @param viewId 值
     */
    private async OnViewChangedAsync(viewId: number): Promise<void> {
        if (import.meta.env.PROD) {
            OrbitCameraComponent.Default.ApplyConfigAsync(viewId);
        } else {
            window.Logger.Debug(`视角切换: ${viewId}`);
        }
    }

    public async RecycleAsync(id: number, instanceId: number): Promise<void> {
        InteractableObjectComponent.Default.Remove(id);
        await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.UncheckInteractableObjectRequest(id, instanceId));
        InteractableObjectComponent.Default.Choices.value.length -= 1        
    }
}

class CalibrationConfig {
    Id: number;
    Name: string;
    Asset: string;
    Options: Array<string>;
    ViewId: number;

    Descriptions: Map<string, string>;
    Records: Map<string, number>;

    /**
     * 物体实例Id
     */
    InstanceId: number;
    /**
     * 原点实例Id
     */
    Origin: number;
    /**
     * 是否显示原点
     */
    ShowOrigin: boolean;
    /**
     * 标定值
     */
    Values: Array<number>;

    constructor(id: number, name: string, asset: string, options: Array<string>, viewId: number, descriptions: Map<string, string>, records: Map<string, number>, instanceId: number = 0, origin: number = 0, showOrigin: boolean = false, values: Array<number> = []) {
        this.Id = id;
        this.Name = name;
        this.Asset = asset;
        this.Options = options;
        this.ViewId = viewId;

        this.Descriptions = descriptions;
        this.Records = records;

        this.InstanceId = instanceId;
        this.Origin = origin;
        this.ShowOrigin = showOrigin;
        this.Values = values;
    }
}

/**
 * 标定组件
 */
export class CalibrationComponent {
    private static instance: CalibrationComponent = new CalibrationComponent();
    /**
     * 标定组件
     */
    public static get Default(): CalibrationComponent {
        return this.instance;
    }

    constructor() {
        window.addEventListener('unload', this.Dispose.bind(this));

        this.watchStopHandles.push(watch(this.Id, this.OnIdChangedAsync.bind(this)));
        this.watchStopHandles.push(watch(this.ShowOrigin, this.OnOriginStateChangedAsync.bind(this)));
        this.watchStopHandles.push(watch(this.ShowTips, this.OnPopupChangedAsync.bind(this)));
        this.watchStopHandles.push(watch(this.ShowForms, this.OnPopupChangedAsync.bind(this)));
    }

    Dispose() {
        window.removeEventListener('unload', this.Dispose);

        for (const watchStopHandle of this.watchStopHandles) {
            watchStopHandle();
        }
        this.watchStopHandles.clear();
    }

    public Configs: UnwrapNestedRefs<Map<number, CalibrationConfig>> = reactive(ToMap<number, CalibrationConfig>([
        new CalibrationConfig(1, '车辆坐标系标定',
        'Assets/R00062/ICV/Res/Product/Calibration/激光雷达标定/新石器激光雷达车辆坐标系标定.prefab',
            ['显示原点', '标定说明', '参数标定'],
            3039,
            new Map<string, string>([
                ["Car_W", "车辆左侧至右侧距离:"],
                ["Car_L", "车辆前侧至后侧距离:"],
                ["Radar_X", "激光雷达至车辆左侧距离:"],
                ["Radar_Y", "激光雷达至车辆前侧距离:"],
                ["Radar_Z", "激光雷达至地面高度:"],
                ["Source_X", "车辆轮轴中心至车辆左侧距离:"],
                ["Source_Y", "车辆轮轴中心至车辆前(后)侧距离:"],
                ["Source_Z", "车辆轮轴中心至地面距离:"],
            ]),
            new Map<string, number>([
                ["Car_W", 0],
                ["Car_L", 0],
                ["Radar_X", 0],
                ["Radar_Y", 0],
                ["Radar_Z", 0],
                ["Source_X", 0],
                ["Source_Y", 0],
                ["Source_Z", 0],
            ]),
        ),
    ], element => element.Id));

    /**
     * 当前标定配置Id
     */
    public Id: Ref<number> = ref(1);

    public Config: ComputedRef<CalibrationConfig> = computed(() => this.Configs.get(this.Id.value)!);

    public Options: ComputedRef<Array<string>> = computed(() => this.Config.value.Options);

    /**
     * 姿态标定角度
     */
    private attibuteAngles: Array<number> = [0, 0, 0];

    public Tips = [
        '标定说明001.png',
        '标定说明002.png',
    ];

    /**
    * 显示原点
    */
    public ShowOrigin: Ref<boolean> = ref(false);
    /**
     * 显示标定说明
     */
    public ShowTips: Ref<boolean> = ref(false);
    /**
     * 显示参数标定
     */
    public ShowForms: Ref<boolean> = ref(false);

    // 标定X
    public pointX: Ref<any> = ref(0)
    // 标定Y
    public pointY: Ref<any> = ref(0)
    // 标定Z
    public pointZ: Ref<any> = ref(0)

    public AttitudeState: Ref<boolean> = ref(false);
    public AttitudePercent: Ref<number> = ref(0);

    private hasInitialized: boolean = false;

    private volume: number = 0;
    private effect: number = 0;

    private watchStopHandles: Array<WatchStopHandle> = [];

    public async Awake(): Promise<void> {
        const lock = await LidarComponent.Default.WaitAsync();

        WebWindowComponent.Default.SetTransparentBackground();
        TooltipComponent.Default.Clear();

        await RoomComponent.Default.ShowAsync();

        if (!this.hasInitialized) {
            await this.LoadAsync();
            this.hasInitialized = true;
        }

        await GameObjectComponent.Default.ShowAsync(this.Config.value.InstanceId);
        await OrbitCameraComponent.Default.ApplyConfigAsync(this.Config.value.ViewId);

        lock.Dispose();
    }

    public async Destroy(): Promise<void> {
        const lock = await LidarComponent.Default.WaitAsync();

        await GameObjectComponent.Default.HideAsync(this.Config.value.InstanceId);

        await RoomComponent.Default.HideAsync();

        // 隐藏坐标系尺寸标注
        TooltipComponent.Default.Clear();

        lock.Dispose();
    }

    /**
     * 切换原点显示状态
     * @param value 状态
     */
    private async OnOriginStateChangedAsync(value: boolean): Promise<void> {
        this.Config.value.ShowOrigin = value;

        if (value) {
            await GameObjectComponent.Default.ShowAsync(this.Config.value.Origin);
        } else {
            await GameObjectComponent.Default.HideAsync(this.Config.value.Origin);
        }
    }

    private async OnPopupChangedAsync(value: boolean): Promise<void> {
        if (value) {
            this.volume = await PostProcessLayerComponent.Default.AddVolumeAsync();
            this.effect = await PostProcessLayerComponent.Default.AddKawaseBlurAsync(this.volume);
        } else {
            await PostProcessLayerComponent.Default.RemoveEffectAsync(this.volume, this.effect);
            await PostProcessLayerComponent.Default.RemoveVolumeAsync(this.volume);
        }
    }

    private async LoadAsync(): Promise<void> {
        if (import.meta.env.DEV) {
            return;
        }

        const volume = await PostProcessLayerComponent.Default.AddVolumeAsync();
        const effect = await PostProcessLayerComponent.Default.AddKawaseBlurAsync(volume);

        const instanceIds = await AssetLoaderComponent.Default.LoadAllAsync(Array.from(this.Configs.values()).map(config => config.Asset));
        await GameObjectComponent.Default.HideAsync(instanceIds);
        const keys = Array.from(this.Configs.keys());
        for (let i = 0; i < keys.length; ++i) {
            this.Configs.get(keys[i])!.InstanceId = instanceIds[i];
        }

        // 初始化坐标系标定
        const gizmos: ClientMessage.LaserRadarGizmosResponse = await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.LaserRadarGizmosRequest(this.Configs.get(1)!.InstanceId));
        this.Config.value.Origin = gizmos.Origin;
        this.Config.value.Values.addRange(gizmos.Values.map(value => Math.round(value * Math.pow(10, 2)) / Math.pow(10, 2)));

        // 初始化姿态标定
        // const attitude: ClientMessage.MillimeterWaveRadarAttitudeResponse = await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.MillimeterWaveRadarAttitudeRequest(this.Configs.get(2)!.InstanceId));
        // const config = this.Configs.get(2)!;
        // config.Records.set('Yaw', attitude.Yaw);
        // config.Records.set('Pitch', attitude.Pitch);
        // config.Records.set('Roll', attitude.Roll);
        // config.Records.set('Distance', attitude.Distance);

        await PostProcessLayerComponent.Default.RemoveEffectAsync(volume, effect);
        await PostProcessLayerComponent.Default.RemoveVolumeAsync(volume);
    }

    /**
     * 标定Id发生变化时
     * @param current 值
     */
    private async OnIdChangedAsync(current: number, previous: number): Promise<void> {
        if (import.meta.env.PROD) {
            TooltipComponent.Default.Clear();

            await GameObjectComponent.Default.HideAsync(this.Configs.get(previous)!.InstanceId);

            await GameObjectComponent.Default.ShowAsync(this.Config.value.InstanceId);

            await OrbitCameraComponent.Default.ApplyConfigAsync(this.Config.value.ViewId);
        }

        this.ShowOrigin.value = this.Config.value.ShowOrigin;
    }

    public async OnAttitudeAnglesUpdateAsync(yaw: number, pitch: number, roll: number): Promise<boolean> {
        if (this.attibuteAngles[0] == yaw && this.attibuteAngles[1] == pitch && this.attibuteAngles[2] == roll) {
            return false;
        }
        this.attibuteAngles[0] = yaw;
        this.attibuteAngles[1] = pitch;
        this.attibuteAngles[2] = roll;

        const response = await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.MillimeterWaveRadarAttitudeAnglesUpdateRequest(yaw, pitch, roll));
        return response.Error == 0;
    }

    public async SubmitAttitudeAsync(yaw: number, pitch: number, roll: number): Promise<void> {
        this.volume = await PostProcessLayerComponent.Default.AddVolumeAsync();
        this.effect = await PostProcessLayerComponent.Default.AddKawaseBlurAsync(this.volume);

        const standardYaw = this.Config.value.Records.get('Yaw')!;
        const standardPitch = this.Config.value.Records.get('Pitch')!;
        const standardRoll = this.Config.value.Records.get('Roll')!;

        const max = Math.sqrt(Math.pow(standardYaw, 2) + Math.pow(standardPitch, 2) + Math.pow(standardRoll, 2));
        const current = Math.sqrt(Math.pow(yaw - standardYaw, 2) + Math.pow(pitch - standardPitch, 2) + Math.pow(roll - standardRoll, 2));
        const percent = 100 - Math.clamp(current / max * 100 | 0, 0, 100);

        // 95~100 优秀
        // 90~95 良好
        // 80~90 合格
        // ~80 不合格

        this.AttitudePercent.value = percent;
        this.AttitudeState.value = true;
    }

    public async ConfirmAttitudeAsync(): Promise<void> {
        this.AttitudeState.value = false;

        await PostProcessLayerComponent.Default.RemoveEffectAsync(this.volume, this.effect);
        await PostProcessLayerComponent.Default.RemoveVolumeAsync(this.volume);
    }

    public async SubmitGizmosAsync(values: Array<number>): Promise<void> {
        const keys = Array.from(this.Configs.keys());
        const success = values.map(value => Math.round(value * Math.pow(10, 2)) / Math.pow(10, 2)).toString() == this.Configs.get(keys[0])!.Values.toString();
        const options = ModalOptions.Default()
            .WithPrefix('/src/components/Apps/Lidar/')
            .WithType('MessageBox')
            .WithContent(success ? '标定成功' : '标定失败')
            .WithButtons(['确定']);
        await ModalComponent.Default.PopupAsync(options);
    }
}

/**
 * 协议定义
 */
export class ProtocolDefinitionConfig {
    Id: number;
    Type: number;
    Sign: string;
    StartIndex: string;
    Length: string;
    Min: string;
    Max: string;
    Resolution: string;
    Unit: string;
    Description: string;

    Value: string = '';
    Reference: string = '';

    constructor(id: number, type: number, sign: string, startIndex: string, length: string, min: string, max: string, resolution: string, unit: string, description: string) {
        this.Id = id;
        this.Type = type;
        this.Sign = sign;
        this.StartIndex = startIndex;
        this.Length = length;
        this.Min = min;
        this.Max = max;
        this.Resolution = resolution;
        this.Unit = unit;
        this.Description = description;
    }
}

//#region 线束类型

// 0 ◀————————
// 1 ◀————————◁
// 2 ◀————————◀
// 3 ◁————————
// 4 ◁————————◁
// 5 ◁————————◀
// 6  ————————
// 7  ————————◁
// 8  ————————◀

//#endregion

/**
 * 协议图表定义
 */
export class ProtocolGraphConfig {
    Id: number;
    Type: number;
    Index: number;
    Line: string;
    LT: string;
    LB: string;
    Color: string;

    constructor(id: number, type: number, index: number, line: string, lt: string, lb: string, color: string) {
        this.Id = id;
        this.Type = type;
        this.Index = index;
        this.Line = line;
        this.LT = lt;
        this.LB = lb;
        this.Color = color;
    }
}

/**
 * 协议帧
 */
export class ProtocolFrame {
    /**
     * 帧头
     */
    public Header: string = '55 AA 05 5A';
    /**
     * 帧尾
     */
        public Tail: string = '00 FF';
    /**
     * 协议版本号
     */
    public ProtocoIVersion: number = 0;
    /**
     * 主板下发包计数
     */
    public MainBoardCount: number = 0;
    /**
     * 底板上传包计数
     */
    public BaseBoardCount: number = 0;
    /**
     * 测距精度标记
     */
    public DistanceRatio: number = 0;
    /**
     * 角度脉冲间隔计数
     */
    public AnglePulseCount: number = 0;
    /**
     * 时间戳秒
     */
    public Second: number = 0;
    /**
     * 时间戳微秒
     */
    public MilliSecond: number = 0;
    /**
     * 类型
     */
    public LidarType: number = 0;
    /**
     * 数据包头
     */
    public DataBlockHeader: string = 'FF EE';
    /**
     * 水平旋转角度
     */
    public Azimuth: number = 0;
    /**
     * 距离
     */
    public Distance: number = 0;
    /**
     * 反射率
     */
    public Reflectivity: number = 0;

}

export class ProtocolDefinition {
    public Id: number;
    public Name: string;
    public Value: string;
    public Reference: string;

    constructor(id: number, name: string, value: string = '', reference: string = '') {
        this.Id = id;
        this.Name = name;
        this.Value = value;
        this.Reference = reference;
    }
}

/**
 * 协议解读组件
 */
export class ProtocolComponent {
    private static instance: ProtocolComponent = new ProtocolComponent();
    /**
     * 协议解读组件
     */
    public static get Default(): ProtocolComponent {
        return this.instance;
    }

    constructor() {
        window.addEventListener('unload', this.Dispose.bind(this));
        // this.watchStopHandles.push(watch(this.Type, this.OnTypeChangedAsync.bind(this)));
        this.watchStopHandles.push(watch(this.DataSource, this.OnDataSourceChanged.bind(this)));
    }

    Dispose() {
        window.removeEventListener('unload', this.Dispose);

        for (const watchStopHandle of this.watchStopHandles) {
            watchStopHandle();
        }
        this.watchStopHandles.clear();
    }

    // public GraphConfigs: Array<ProtocolGraphConfig> = [
    //     { "Id": 1001, "Type": 0x201, "Index": 7, "Line": "2", "LT": "RadarState_NVMwriteStatus", "LB": "", "Color": "orange" },
    //     { "Id": 1002, "Type": 0x201, "Index": 6, "Line": "2", "LT": "RadarState_NVMReadStatus", "LB": "", "Color": "lime" },
    //     { "Id": 1003, "Type": 0x201, "Index": 5, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 1004, "Type": 0x201, "Index": 4, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 1005, "Type": 0x201, "Index": 3, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 1006, "Type": 0x201, "Index": 2, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 1007, "Type": 0x201, "Index": 1, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 1008, "Type": 0x201, "Index": 0, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 1009, "Type": 0x201, "Index": 15, "Line": "0", "LT": "RadarState_MaxDistanceCfg", "LB": "msb", "Color": "teal" },
    //     { "Id": 1010, "Type": 0x201, "Index": 14, "Line": "6", "LT": "", "LB": "", "Color": "teal" },
    //     { "Id": 1011, "Type": 0x201, "Index": 13, "Line": "6", "LT": "", "LB": "", "Color": "teal" },
    //     { "Id": 1012, "Type": 0x201, "Index": 12, "Line": "6", "LT": "", "LB": "", "Color": "teal" },
    //     { "Id": 1013, "Type": 0x201, "Index": 11, "Line": "6", "LT": "", "LB": "", "Color": "teal" },
    //     { "Id": 1014, "Type": 0x201, "Index": 10, "Line": "6", "LT": "", "LB": "", "Color": "teal" },
    //     { "Id": 1015, "Type": 0x201, "Index": 9, "Line": "6", "LT": "", "LB": "", "Color": "teal" },
    //     { "Id": 1016, "Type": 0x201, "Index": 8, "Line": "7", "LT": "", "LB": "", "Color": "teal" },
    //     { "Id": 1017, "Type": 0x201, "Index": 23, "Line": "3", "LT": "", "LB": "", "Color": "teal" },
    //     { "Id": 1018, "Type": 0x201, "Index": 22, "Line": "8", "LT": "RadarState_MaxDistanceCfg", "LB": "lsb", "Color": "teal" },
    //     { "Id": 1019, "Type": 0x201, "Index": 21, "Line": "2", "LT": "RadarState_Persistent_Error", "LB": "", "Color": "aquamarine" },
    //     { "Id": 1020, "Type": 0x201, "Index": 20, "Line": "2", "LT": "RadarState_Interference", "LB": "", "Color": "chocolate" },
    //     { "Id": 1021, "Type": 0x201, "Index": 19, "Line": "2", "LT": "RadarState_Temperature_Error", "LB": "", "Color": "cornflowerblue" },
    //     { "Id": 1022, "Type": 0x201, "Index": 18, "Line": "2", "LT": "RadarState_Temporary_Error", "LB": "", "Color": "aqua" },
    //     { "Id": 1023, "Type": 0x201, "Index": 17, "Line": "2", "LT": "RadarState_Voltage_Error", "LB": "", "Color": "chartreuse" },
    //     { "Id": 1024, "Type": 0x201, "Index": 16, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 1025, "Type": 0x201, "Index": 31, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 1026, "Type": 0x201, "Index": 30, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 1027, "Type": 0x201, "Index": 29, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 1028, "Type": 0x201, "Index": 28, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 1029, "Type": 0x201, "Index": 27, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 1030, "Type": 0x201, "Index": 26, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 1031, "Type": 0x201, "Index": 25, "Line": "0", "LT": "RadarState_RadarPowerCfg", "LB": "msb", "Color": "hotpink" },
    //     { "Id": 1032, "Type": 0x201, "Index": 24, "Line": "7", "LT": "", "LB": "", "Color": "hotpink" },
    //     { "Id": 1033, "Type": 0x201, "Index": 39, "Line": "5", "LT": "RadarState_RadarPowerCfg", "LB": "lsb", "Color": "hotpink" },
    //     { "Id": 1034, "Type": 0x201, "Index": 38, "Line": "0", "LT": "RadarState_SortIndex", "LB": "msb", "Color": "forestgreen" },
    //     { "Id": 1035, "Type": 0x201, "Index": 37, "Line": "6", "LT": "", "LB": "", "Color": "forestgreen" },
    //     { "Id": 1036, "Type": 0x201, "Index": 36, "Line": "8", "LT": "", "LB": "lsb", "Color": "forestgreen" },
    //     { "Id": 1037, "Type": 0x201, "Index": 35, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 1038, "Type": 0x201, "Index": 34, "Line": "0", "LT": "RadarState_SensorID", "LB": "msb", "Color": "greenyellow" },
    //     { "Id": 1039, "Type": 0x201, "Index": 33, "Line": "6", "LT": "", "LB": "", "Color": "greenyellow" },
    //     { "Id": 1040, "Type": 0x201, "Index": 32, "Line": "8", "LT": "", "LB": "lsb", "Color": "greenyellow" },
    //     { "Id": 1041, "Type": 0x201, "Index": 47, "Line": "0", "LT": "RadarState_MotionRxState", "LB": "msb", "Color": "lightsalmon" },
    //     { "Id": 1042, "Type": 0x201, "Index": 46, "Line": "8", "LT": "", "LB": "lsb", "Color": "lightsalmon" },
    //     { "Id": 1043, "Type": 0x201, "Index": 45, "Line": "2", "LT": "RadarState_SendExtInfoCfg", "LB": "", "Color": "magenta" },
    //     { "Id": 1044, "Type": 0x201, "Index": 44, "Line": "2", "LT": "RadarState_SendQualityCfg", "LB": "", "Color": "lightgreen" },
    //     { "Id": 1045, "Type": 0x201, "Index": 43, "Line": "0", "LT": "RadarState_OutputTypeCfg", "LB": "msb", "Color": "limegreen" },
    //     { "Id": 1046, "Type": 0x201, "Index": 42, "Line": "8", "LT": "", "LB": "lsb", "Color": "limegreen" },
    //     { "Id": 1047, "Type": 0x201, "Index": 41, "Line": "2", "LT": "RadarState_CtrlRelayCfg", "LB": "", "Color": "lightseagreen" },
    //     { "Id": 1048, "Type": 0x201, "Index": 40, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 1049, "Type": 0x201, "Index": 55, "Line": "0", "LT": "RadarState_InvalidClusters", "LB": "msb", "Color": "mediumvioletred" },
    //     { "Id": 1050, "Type": 0x201, "Index": 54, "Line": "6", "LT": "", "LB": "", "Color": "mediumvioletred" },
    //     { "Id": 1051, "Type": 0x201, "Index": 53, "Line": "6", "LT": "", "LB": "", "Color": "mediumvioletred" },
    //     { "Id": 1052, "Type": 0x201, "Index": 52, "Line": "6", "LT": "", "LB": "", "Color": "mediumvioletred" },
    //     { "Id": 1053, "Type": 0x201, "Index": 51, "Line": "6", "LT": "", "LB": "", "Color": "mediumvioletred" },
    //     { "Id": 1054, "Type": 0x201, "Index": 50, "Line": "6", "LT": "", "LB": "", "Color": "mediumvioletred" },
    //     { "Id": 1055, "Type": 0x201, "Index": 49, "Line": "6", "LT": "", "LB": "", "Color": "mediumvioletred" },
    //     { "Id": 1056, "Type": 0x201, "Index": 48, "Line": "8", "LT": "", "LB": "lsb", "Color": "mediumvioletred" },
    //     { "Id": 1057, "Type": 0x201, "Index": 63, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 1058, "Type": 0x201, "Index": 62, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 1059, "Type": 0x201, "Index": 61, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 1060, "Type": 0x201, "Index": 60, "Line": "0", "LT": "RadarState_RCS_Threshold", "LB": "msb", "Color": "navajowhite" },
    //     { "Id": 1061, "Type": 0x201, "Index": 59, "Line": "6", "LT": "", "LB": "", "Color": "navajowhite" },
    //     { "Id": 1062, "Type": 0x201, "Index": 58, "Line": "8", "LT": "", "LB": "lsb", "Color": "navajowhite" },
    //     { "Id": 1063, "Type": 0x201, "Index": 57, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 1064, "Type": 0x201, "Index": 56, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 4001, "Type": 0x408, "Index": 7, "Line": "0", "LT": "CollDetState_NofRegions", "LB": "msb", "Color": "lime" },
    //     { "Id": 4002, "Type": 0x408, "Index": 6, "Line": "6", "LT": "", "LB": "", "Color": "lime" },
    //     { "Id": 4003, "Type": 0x408, "Index": 5, "Line": "6", "LT": "", "LB": "", "Color": "lime" },
    //     { "Id": 4004, "Type": 0x408, "Index": 4, "Line": "8", "LT": "", "LB": "lsb", "Color": "lime" },
    //     { "Id": 4005, "Type": 0x408, "Index": 3, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 4006, "Type": 0x408, "Index": 2, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 4007, "Type": 0x408, "Index": 1, "Line": "2", "LT": "CollDetState_Activation", "LB": "", "Color": "green" },
    //     { "Id": 4008, "Type": 0x408, "Index": 0, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 4009, "Type": 0x408, "Index": 15, "Line": "0", "LT": "CollDetState_MinDetectTime", "LB": "msb", "Color": "teal" },
    //     { "Id": 4010, "Type": 0x408, "Index": 14, "Line": "6", "LT": "", "LB": "", "Color": "teal" },
    //     { "Id": 4011, "Type": 0x408, "Index": 13, "Line": "6", "LT": "", "LB": "", "Color": "teal" },
    //     { "Id": 4012, "Type": 0x408, "Index": 12, "Line": "6", "LT": "", "LB": "", "Color": "teal" },
    //     { "Id": 4013, "Type": 0x408, "Index": 11, "Line": "6", "LT": "", "LB": "", "Color": "teal" },
    //     { "Id": 4014, "Type": 0x408, "Index": 10, "Line": "6", "LT": "", "LB": "", "Color": "teal" },
    //     { "Id": 4015, "Type": 0x408, "Index": 9, "Line": "6", "LT": "", "LB": "", "Color": "teal" },
    //     { "Id": 4016, "Type": 0x408, "Index": 8, "Line": "8", "LT": "", "LB": "lsb", "Color": "teal" },
    //     { "Id": 4017, "Type": 0x408, "Index": 23, "Line": "0", "LT": "CollDetState_MeasCounter", "LB": "msb", "Color": "hotpink" },
    //     { "Id": 4018, "Type": 0x408, "Index": 22, "Line": "6", "LT": "", "LB": "", "Color": "hotpink" },
    //     { "Id": 4019, "Type": 0x408, "Index": 21, "Line": "6", "LT": "", "LB": "", "Color": "hotpink" },
    //     { "Id": 4020, "Type": 0x408, "Index": 20, "Line": "6", "LT": "", "LB": "", "Color": "hotpink" },
    //     { "Id": 4021, "Type": 0x408, "Index": 19, "Line": "6", "LT": "", "LB": "", "Color": "hotpink" },
    //     { "Id": 4022, "Type": 0x408, "Index": 18, "Line": "6", "LT": "", "LB": "", "Color": "hotpink" },
    //     { "Id": 4023, "Type": 0x408, "Index": 17, "Line": "6", "LT": "", "LB": "", "Color": "hotpink" },
    //     { "Id": 4024, "Type": 0x408, "Index": 16, "Line": "7", "LT": "", "LB": "", "Color": "hotpink" },
    //     { "Id": 4025, "Type": 0x408, "Index": 31, "Line": "3", "LT": "CollDetState_MeasCounter", "LB": "", "Color": "hotpink" },
    //     { "Id": 4026, "Type": 0x408, "Index": 30, "Line": "6", "LT": "", "LB": "", "Color": "hotpink" },
    //     { "Id": 4027, "Type": 0x408, "Index": 29, "Line": "6", "LT": "", "LB": "", "Color": "hotpink" },
    //     { "Id": 4028, "Type": 0x408, "Index": 28, "Line": "6", "LT": "", "LB": "", "Color": "hotpink" },
    //     { "Id": 4029, "Type": 0x408, "Index": 27, "Line": "6", "LT": "", "LB": "", "Color": "hotpink" },
    //     { "Id": 4030, "Type": 0x408, "Index": 26, "Line": "6", "LT": "", "LB": "", "Color": "hotpink" },
    //     { "Id": 4031, "Type": 0x408, "Index": 25, "Line": "6", "LT": "", "LB": "", "Color": "hotpink" },
    //     { "Id": 4032, "Type": 0x408, "Index": 24, "Line": "8", "LT": "", "LB": "lsb", "Color": "hotpink" },
    //     { "Id": 5001, "Type": 0x402, "Index": 7, "Line": "0", "LT": "CollDetRegState_RegionID", "LB": "msb", "Color": "#84ff42" },
    //     { "Id": 5002, "Type": 0x402, "Index": 6, "Line": "6", "LT": "", "LB": "", "Color": "#84ff42" },
    //     { "Id": 5003, "Type": 0x402, "Index": 5, "Line": "8", "LT": "", "LB": "lsb", "Color": "#84ff42" },
    //     { "Id": 5004, "Type": 0x402, "Index": 4, "Line": "0", "LT": "CollDetRegState_WarningLevel", "LB": "msb", "Color": "#ff8442" },
    //     { "Id": 5005, "Type": 0x402, "Index": 3, "Line": "8", "LT": "", "LB": "lsb", "Color": "#ff8442" },
    //     { "Id": 5006, "Type": 0x402, "Index": 2, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 5007, "Type": 0x402, "Index": 1, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 5008, "Type": 0x402, "Index": 0, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 5009, "Type": 0x402, "Index": 15, "Line": "0", "LT": "CollDetRegState_Point1X", "LB": "msb", "Color": "#4284c4" },
    //     { "Id": 5010, "Type": 0x402, "Index": 14, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 5011, "Type": 0x402, "Index": 13, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 5012, "Type": 0x402, "Index": 12, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 5013, "Type": 0x402, "Index": 11, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 5014, "Type": 0x402, "Index": 10, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 5015, "Type": 0x402, "Index": 9, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 5016, "Type": 0x402, "Index": 8, "Line": "7", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 5017, "Type": 0x402, "Index": 23, "Line": "3", "LT": "CollDetRegState_Point1X", "LB": "", "Color": "#4284c4" },
    //     { "Id": 5018, "Type": 0x402, "Index": 22, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 5019, "Type": 0x402, "Index": 21, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 5020, "Type": 0x402, "Index": 20, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 5021, "Type": 0x402, "Index": 19, "Line": "8", "LT": "", "LB": "lsb", "Color": "#4284c4" },
    //     { "Id": 5022, "Type": 0x402, "Index": 18, "Line": "0", "LT": "CollDetRegState_Point1Y", "LB": "msb", "Color": "#ffc484" },
    //     { "Id": 5023, "Type": 0x402, "Index": 17, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 5024, "Type": 0x402, "Index": 16, "Line": "7", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 5025, "Type": 0x402, "Index": 31, "Line": "3", "LT": "CollDetRegState_Point1Y", "LB": "", "Color": "#ffc484" },
    //     { "Id": 5026, "Type": 0x402, "Index": 30, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 5027, "Type": 0x402, "Index": 29, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 5028, "Type": 0x402, "Index": 28, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 5029, "Type": 0x402, "Index": 27, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 5030, "Type": 0x402, "Index": 26, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 5031, "Type": 0x402, "Index": 25, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 5032, "Type": 0x402, "Index": 24, "Line": "8", "LT": "", "LB": "lsb", "Color": "#ffc484" },
    //     { "Id": 5033, "Type": 0x402, "Index": 39, "Line": "0", "LT": "CollDetRegState_Point2X", "LB": "msb", "Color": "#42ff84" },
    //     { "Id": 5034, "Type": 0x402, "Index": 38, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 5035, "Type": 0x402, "Index": 37, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 5036, "Type": 0x402, "Index": 36, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 5037, "Type": 0x402, "Index": 35, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 5038, "Type": 0x402, "Index": 34, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 5039, "Type": 0x402, "Index": 33, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 5040, "Type": 0x402, "Index": 32, "Line": "7", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 5041, "Type": 0x402, "Index": 47, "Line": "3", "LT": "CollDetRegState_Point2X", "LB": "", "Color": "#42ff84" },
    //     { "Id": 5042, "Type": 0x402, "Index": 46, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 5043, "Type": 0x402, "Index": 45, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 5044, "Type": 0x402, "Index": 44, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 5045, "Type": 0x402, "Index": 43, "Line": "8", "LT": "", "LB": "lsb", "Color": "#42ff84" },
    //     { "Id": 5046, "Type": 0x402, "Index": 42, "Line": "0", "LT": "CollDetRegState_Point2Y", "LB": "msb", "Color": "#ff84c4" },
    //     { "Id": 5047, "Type": 0x402, "Index": 41, "Line": "6", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 5048, "Type": 0x402, "Index": 40, "Line": "7", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 5049, "Type": 0x402, "Index": 55, "Line": "3", "LT": "CollDetRegState_Point2Y", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 5050, "Type": 0x402, "Index": 54, "Line": "6", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 5051, "Type": 0x402, "Index": 53, "Line": "6", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 5052, "Type": 0x402, "Index": 52, "Line": "6", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 5053, "Type": 0x402, "Index": 51, "Line": "6", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 5054, "Type": 0x402, "Index": 50, "Line": "6", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 5055, "Type": 0x402, "Index": 49, "Line": "6", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 5056, "Type": 0x402, "Index": 48, "Line": "8", "LT": "", "LB": "lsb", "Color": "#ff84c4" },
    //     { "Id": 5057, "Type": 0x402, "Index": 63, "Line": "0", "LT": "CollDetRegState_NofObjects", "LB": "msb", "Color": "#84c442" },
    //     { "Id": 5058, "Type": 0x402, "Index": 62, "Line": "6", "LT": "", "LB": "", "Color": "#84c442" },
    //     { "Id": 5059, "Type": 0x402, "Index": 61, "Line": "6", "LT": "", "LB": "", "Color": "#84c442" },
    //     { "Id": 5060, "Type": 0x402, "Index": 60, "Line": "6", "LT": "", "LB": "", "Color": "#84c442" },
    //     { "Id": 5061, "Type": 0x402, "Index": 59, "Line": "6", "LT": "", "LB": "", "Color": "#84c442" },
    //     { "Id": 5062, "Type": 0x402, "Index": 58, "Line": "6", "LT": "", "LB": "", "Color": "#84c442" },
    //     { "Id": 5063, "Type": 0x402, "Index": 57, "Line": "6", "LT": "", "LB": "", "Color": "#84c442" },
    //     { "Id": 5064, "Type": 0x402, "Index": 56, "Line": "8", "LT": "", "LB": "lsb", "Color": "#84c442" },
    //     { "Id": 6001, "Type": 0x700, "Index": 7, "Line": "0", "LT": "Version_MajorRelease", "LB": "msb", "Color": "#42ff84" },
    //     { "Id": 6002, "Type": 0x700, "Index": 6, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 6003, "Type": 0x700, "Index": 5, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 6004, "Type": 0x700, "Index": 4, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 6005, "Type": 0x700, "Index": 3, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 6006, "Type": 0x700, "Index": 2, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 6007, "Type": 0x700, "Index": 1, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 6008, "Type": 0x700, "Index": 0, "Line": "8", "LT": "", "LB": "lsb", "Color": "#42ff84" },
    //     { "Id": 6009, "Type": 0x700, "Index": 15, "Line": "0", "LT": "Version_MinorRelease", "LB": "msb", "Color": "#ffc484" },
    //     { "Id": 6010, "Type": 0x700, "Index": 14, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 6011, "Type": 0x700, "Index": 13, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 6012, "Type": 0x700, "Index": 12, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 6013, "Type": 0x700, "Index": 11, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 6014, "Type": 0x700, "Index": 10, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 6015, "Type": 0x700, "Index": 9, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 6016, "Type": 0x700, "Index": 8, "Line": "8", "LT": "", "LB": "lsb", "Color": "#ffc484" },
    //     { "Id": 6017, "Type": 0x700, "Index": 23, "Line": "0", "LT": "Version_PatchLevel", "LB": "msb", "Color": "#4284c4" },
    //     { "Id": 6018, "Type": 0x700, "Index": 22, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 6019, "Type": 0x700, "Index": 21, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 6020, "Type": 0x700, "Index": 20, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 6021, "Type": 0x700, "Index": 19, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 6022, "Type": 0x700, "Index": 18, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 6023, "Type": 0x700, "Index": 17, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 6024, "Type": 0x700, "Index": 16, "Line": "8", "LT": "", "LB": "lsb", "Color": "#4284c4" },
    //     { "Id": 6025, "Type": 0x700, "Index": 31, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 6026, "Type": 0x700, "Index": 30, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 6027, "Type": 0x700, "Index": 29, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 6028, "Type": 0x700, "Index": 28, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 6029, "Type": 0x700, "Index": 27, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 6030, "Type": 0x700, "Index": 26, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 6031, "Type": 0x700, "Index": 25, "Line": "2", "LT": "Version_ExtendedRange", "LB": "", "Color": "#84ff42" },
    //     { "Id": 6032, "Type": 0x700, "Index": 24, "Line": "2", "LT": "Version_CountryCode", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 7001, "Type": 0x60A, "Index": 7, "Line": "0", "LT": "Object_NofObjects", "LB": "msb", "Color": "#42ff84" },
    //     { "Id": 7002, "Type": 0x60A, "Index": 6, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 7003, "Type": 0x60A, "Index": 5, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 7004, "Type": 0x60A, "Index": 4, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 7005, "Type": 0x60A, "Index": 3, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 7006, "Type": 0x60A, "Index": 2, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 7007, "Type": 0x60A, "Index": 1, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 7008, "Type": 0x60A, "Index": 0, "Line": "8", "LT": "", "LB": "lsb", "Color": "#42ff84" },
    //     { "Id": 7009, "Type": 0x60A, "Index": 15, "Line": "0", "LT": "Object_MeasCounter", "LB": "msb", "Color": "#ffc484" },
    //     { "Id": 7010, "Type": 0x60A, "Index": 14, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 7011, "Type": 0x60A, "Index": 13, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 7012, "Type": 0x60A, "Index": 12, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 7013, "Type": 0x60A, "Index": 11, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 7014, "Type": 0x60A, "Index": 10, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 7015, "Type": 0x60A, "Index": 9, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 7016, "Type": 0x60A, "Index": 8, "Line": "7", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 7017, "Type": 0x60A, "Index": 23, "Line": "3", "LT": "Object_MeasCounter", "LB": "", "Color": "#ffc484" },
    //     { "Id": 7018, "Type": 0x60A, "Index": 22, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 7019, "Type": 0x60A, "Index": 21, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 7020, "Type": 0x60A, "Index": 20, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 7021, "Type": 0x60A, "Index": 19, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 7022, "Type": 0x60A, "Index": 18, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 7023, "Type": 0x60A, "Index": 17, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 7024, "Type": 0x60A, "Index": 16, "Line": "8", "LT": "", "LB": "lsb", "Color": "#ffc484" },
    //     { "Id": 7025, "Type": 0x60A, "Index": 31, "Line": "0", "LT": "Object_InterfaceVersion", "LB": "msb", "Color": "#4284c4" },
    //     { "Id": 7026, "Type": 0x60A, "Index": 30, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 7027, "Type": 0x60A, "Index": 29, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 7028, "Type": 0x60A, "Index": 28, "Line": "8", "LT": "", "LB": "lsb", "Color": "#4284c4" },
    //     { "Id": 7029, "Type": 0x60A, "Index": 27, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 7030, "Type": 0x60A, "Index": 26, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 7031, "Type": 0x60A, "Index": 25, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 7032, "Type": 0x60A, "Index": 24, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 8001, "Type": 0x60B, "Index": 7, "Line": "0", "LT": "Object_ID", "LB": "msb", "Color": "#ff84c4" },
    //     { "Id": 8002, "Type": 0x60B, "Index": 6, "Line": "6", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 8003, "Type": 0x60B, "Index": 5, "Line": "6", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 8004, "Type": 0x60B, "Index": 4, "Line": "6", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 8005, "Type": 0x60B, "Index": 3, "Line": "6", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 8006, "Type": 0x60B, "Index": 2, "Line": "6", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 8007, "Type": 0x60B, "Index": 1, "Line": "6", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 8008, "Type": 0x60B, "Index": 0, "Line": "8", "LT": "", "LB": "lsb", "Color": "#ff84c4" },
    //     { "Id": 8009, "Type": 0x60B, "Index": 15, "Line": "0", "LT": "Object_DistLong", "LB": "msb", "Color": "#42ff84" },
    //     { "Id": 8010, "Type": 0x60B, "Index": 14, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 8011, "Type": 0x60B, "Index": 13, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 8012, "Type": 0x60B, "Index": 12, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 8013, "Type": 0x60B, "Index": 11, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 8014, "Type": 0x60B, "Index": 10, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 8015, "Type": 0x60B, "Index": 9, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 8016, "Type": 0x60B, "Index": 8, "Line": "7", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 8017, "Type": 0x60B, "Index": 23, "Line": "3", "LT": "Object_DistLong", "LB": "", "Color": "#42ff84" },
    //     { "Id": 8018, "Type": 0x60B, "Index": 22, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 8019, "Type": 0x60B, "Index": 21, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 8020, "Type": 0x60B, "Index": 20, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 8021, "Type": 0x60B, "Index": 19, "Line": "8", "LT": "", "LB": "lsb", "Color": "#42ff84" },
    //     { "Id": 8022, "Type": 0x60B, "Index": 18, "Line": "0", "LT": "Object_DistLat", "LB": "msb", "Color": "#4284c4" },
    //     { "Id": 8023, "Type": 0x60B, "Index": 17, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 8024, "Type": 0x60B, "Index": 16, "Line": "7", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 8025, "Type": 0x60B, "Index": 31, "Line": "3", "LT": "Object_DistLat", "LB": "", "Color": "#4284c4" },
    //     { "Id": 8026, "Type": 0x60B, "Index": 30, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 8027, "Type": 0x60B, "Index": 29, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 8028, "Type": 0x60B, "Index": 28, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 8029, "Type": 0x60B, "Index": 27, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 8030, "Type": 0x60B, "Index": 26, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 8031, "Type": 0x60B, "Index": 25, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 8032, "Type": 0x60B, "Index": 24, "Line": "8", "LT": "", "LB": "lsb", "Color": "#4284c4" },
    //     { "Id": 8033, "Type": 0x60B, "Index": 39, "Line": "0", "LT": "Object_VrelLong", "LB": "msb", "Color": "#ffc484" },
    //     { "Id": 8034, "Type": 0x60B, "Index": 38, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 8035, "Type": 0x60B, "Index": 37, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 8036, "Type": 0x60B, "Index": 36, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 8037, "Type": 0x60B, "Index": 35, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 8038, "Type": 0x60B, "Index": 34, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 8039, "Type": 0x60B, "Index": 33, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 8040, "Type": 0x60B, "Index": 32, "Line": "7", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 8041, "Type": 0x60B, "Index": 47, "Line": "3", "LT": "Object_VrelLong", "LB": "", "Color": "#ffc484" },
    //     { "Id": 8042, "Type": 0x60B, "Index": 46, "Line": "8", "LT": "", "LB": "lsb", "Color": "#ffc484" },
    //     { "Id": 8043, "Type": 0x60B, "Index": 45, "Line": "0", "LT": "Object_VrelLat", "LB": "msb", "Color": "#84ff42" },
    //     { "Id": 8044, "Type": 0x60B, "Index": 44, "Line": "6", "LT": "", "LB": "", "Color": "#84ff42" },
    //     { "Id": 8045, "Type": 0x60B, "Index": 43, "Line": "6", "LT": "", "LB": "", "Color": "#84ff42" },
    //     { "Id": 8046, "Type": 0x60B, "Index": 42, "Line": "6", "LT": "", "LB": "", "Color": "#84ff42" },
    //     { "Id": 8047, "Type": 0x60B, "Index": 41, "Line": "6", "LT": "", "LB": "", "Color": "#84ff42" },
    //     { "Id": 8048, "Type": 0x60B, "Index": 40, "Line": "7", "LT": "", "LB": "", "Color": "#84ff42" },
    //     { "Id": 8049, "Type": 0x60B, "Index": 55, "Line": "3", "LT": "Object_VrelLat", "LB": "", "Color": "#84ff42" },
    //     { "Id": 8050, "Type": 0x60B, "Index": 54, "Line": "6", "LT": "", "LB": "", "Color": "#84ff42" },
    //     { "Id": 8051, "Type": 0x60B, "Index": 53, "Line": "8", "LT": "", "LB": "lsb", "Color": "#84ff42" },
    //     { "Id": 8052, "Type": 0x60B, "Index": 52, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 8053, "Type": 0x60B, "Index": 51, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 8054, "Type": 0x60B, "Index": 50, "Line": "0", "LT": "Object_DynProp", "LB": "msb", "Color": "#ff8442" },
    //     { "Id": 8055, "Type": 0x60B, "Index": 49, "Line": "6", "LT": "", "LB": "", "Color": "#ff8442" },
    //     { "Id": 8056, "Type": 0x60B, "Index": 48, "Line": "8", "LT": "", "LB": "lsb", "Color": "#ff8442" },
    //     { "Id": 8057, "Type": 0x60B, "Index": 63, "Line": "0", "LT": "Object_RCS", "LB": "msb", "Color": "#84c442" },
    //     { "Id": 8058, "Type": 0x60B, "Index": 62, "Line": "6", "LT": "", "LB": "", "Color": "#84c442" },
    //     { "Id": 8059, "Type": 0x60B, "Index": 61, "Line": "6", "LT": "", "LB": "", "Color": "#84c442" },
    //     { "Id": 8060, "Type": 0x60B, "Index": 60, "Line": "6", "LT": "", "LB": "", "Color": "#84c442" },
    //     { "Id": 8061, "Type": 0x60B, "Index": 59, "Line": "6", "LT": "", "LB": "", "Color": "#84c442" },
    //     { "Id": 8062, "Type": 0x60B, "Index": 58, "Line": "6", "LT": "", "LB": "", "Color": "#84c442" },
    //     { "Id": 8063, "Type": 0x60B, "Index": 57, "Line": "6", "LT": "", "LB": "", "Color": "#84c442" },
    //     { "Id": 8064, "Type": 0x60B, "Index": 56, "Line": "8", "LT": "", "LB": "lsb", "Color": "#84c442" },
    //     { "Id": 9001, "Type": 0x60C, "Index": 7, "Line": "0", "LT": "Obj_ID", "LB": "msb", "Color": "#4284c4" },
    //     { "Id": 9002, "Type": 0x60C, "Index": 6, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 9003, "Type": 0x60C, "Index": 5, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 9004, "Type": 0x60C, "Index": 4, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 9005, "Type": 0x60C, "Index": 3, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 9006, "Type": 0x60C, "Index": 2, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 9007, "Type": 0x60C, "Index": 1, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 9008, "Type": 0x60C, "Index": 0, "Line": "8", "LT": "", "LB": "lsb", "Color": "#4284c4" },
    //     { "Id": 9009, "Type": 0x60C, "Index": 15, "Line": "0", "LT": "Obj_DistLong_rms", "LB": "msb", "Color": "#42ff84" },
    //     { "Id": 9010, "Type": 0x60C, "Index": 14, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 9011, "Type": 0x60C, "Index": 13, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 9012, "Type": 0x60C, "Index": 12, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 9013, "Type": 0x60C, "Index": 11, "Line": "8", "LT": "", "LB": "lsb", "Color": "#42ff84" },
    //     { "Id": 9014, "Type": 0x60C, "Index": 10, "Line": "0", "LT": "Obj_DistLat_rms", "LB": "msb", "Color": "#ffc484" },
    //     { "Id": 9015, "Type": 0x60C, "Index": 9, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 9016, "Type": 0x60C, "Index": 8, "Line": "7", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 9017, "Type": 0x60C, "Index": 23, "Line": "3", "LT": "Obj_DistLat_rms", "LB": "", "Color": "#ffc484" },
    //     { "Id": 9018, "Type": 0x60C, "Index": 22, "Line": "8", "LT": "", "LB": "lsb", "Color": "#ffc484" },
    //     { "Id": 9019, "Type": 0x60C, "Index": 21, "Line": "0", "LT": "Obj_VrelLong_rms", "LB": "msb", "Color": "#84c442" },
    //     { "Id": 9020, "Type": 0x60C, "Index": 20, "Line": "6", "LT": "", "LB": "", "Color": "#84c442" },
    //     { "Id": 9021, "Type": 0x60C, "Index": 19, "Line": "6", "LT": "", "LB": "", "Color": "#84c442" },
    //     { "Id": 9022, "Type": 0x60C, "Index": 18, "Line": "6", "LT": "", "LB": "", "Color": "#84c442" },
    //     { "Id": 9023, "Type": 0x60C, "Index": 17, "Line": "8", "LT": "", "LB": "lsb", "Color": "#84c442" },
    //     { "Id": 9024, "Type": 0x60C, "Index": 16, "Line": "1", "LT": "Obj_VrelLat_rms", "LB": "msb", "Color": "#84ff42" },
    //     { "Id": 9025, "Type": 0x60C, "Index": 31, "Line": "7", "LT": "Obj_VrelLat_rms", "LB": "", "Color": "#84ff42" },
    //     { "Id": 9026, "Type": 0x60C, "Index": 30, "Line": "6", "LT": "", "LB": "", "Color": "#84ff42" },
    //     { "Id": 9027, "Type": 0x60C, "Index": 29, "Line": "6", "LT": "", "LB": "", "Color": "#84ff42" },
    //     { "Id": 9028, "Type": 0x60C, "Index": 28, "Line": "8", "LT": "", "LB": "lsb", "Color": "#84ff42" },
    //     { "Id": 9029, "Type": 0x60C, "Index": 27, "Line": "0", "LT": "Obj_ArelLong_rms", "LB": "msb", "Color": "#c44284" },
    //     { "Id": 9030, "Type": 0x60C, "Index": 26, "Line": "6", "LT": "", "LB": "", "Color": "#c44284" },
    //     { "Id": 9031, "Type": 0x60C, "Index": 25, "Line": "6", "LT": "", "LB": "", "Color": "#c44284" },
    //     { "Id": 9032, "Type": 0x60C, "Index": 24, "Line": "3", "LT": "", "LB": "", "Color": "#c44284" },
    //     { "Id": 9033, "Type": 0x60C, "Index": 39, "Line": "5", "LT": "Obj_ArelLong_rms", "LB": "lsb", "Color": "#c44284" },
    //     { "Id": 9034, "Type": 0x60C, "Index": 38, "Line": "0", "LT": "Obj_ArelLat_rms", "LB": "msb", "Color": "#ff8442" },
    //     { "Id": 9035, "Type": 0x60C, "Index": 37, "Line": "6", "LT": "", "LB": "", "Color": "#ff8442" },
    //     { "Id": 9036, "Type": 0x60C, "Index": 36, "Line": "6", "LT": "", "LB": "", "Color": "#ff8442" },
    //     { "Id": 9037, "Type": 0x60C, "Index": 35, "Line": "6", "LT": "", "LB": "", "Color": "#ff8442" },
    //     { "Id": 9038, "Type": 0x60C, "Index": 34, "Line": "8", "LT": "", "LB": "lsb", "Color": "#ff8442" },
    //     { "Id": 9039, "Type": 0x60C, "Index": 33, "Line": "0", "LT": "Obj_Orientation_rms", "LB": "msb", "Color": "#ff84c4" },
    //     { "Id": 9040, "Type": 0x60C, "Index": 32, "Line": "7", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 9041, "Type": 0x60C, "Index": 47, "Line": "3", "LT": "Obj_Orientation_rms", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 9042, "Type": 0x60C, "Index": 46, "Line": "6", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 9043, "Type": 0x60C, "Index": 45, "Line": "8", "LT": "", "LB": "lsb", "Color": "#ff84c4" },
    //     { "Id": 9044, "Type": 0x60C, "Index": 44, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 9045, "Type": 0x60C, "Index": 43, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 9046, "Type": 0x60C, "Index": 42, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 9047, "Type": 0x60C, "Index": 41, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 9048, "Type": 0x60C, "Index": 40, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 9049, "Type": 0x60C, "Index": 55, "Line": "0", "LT": "Obj_ProbOfExist", "LB": "msb", "Color": "#42c4ff" },
    //     { "Id": 9050, "Type": 0x60C, "Index": 54, "Line": "6", "LT": "", "LB": "", "Color": "#42c4ff" },
    //     { "Id": 9051, "Type": 0x60C, "Index": 53, "Line": "8", "LT": "", "LB": "lsb", "Color": "#42c4ff" },
    //     { "Id": 9052, "Type": 0x60C, "Index": 52, "Line": "0", "LT": "Obj_MeasState", "LB": "msb", "Color": "#c4ff84" },
    //     { "Id": 9053, "Type": 0x60C, "Index": 51, "Line": "6", "LT": "", "LB": "", "Color": "#c4ff84" },
    //     { "Id": 9054, "Type": 0x60C, "Index": 50, "Line": "8", "LT": "", "LB": "lsb", "Color": "#c4ff84" },
    //     { "Id": 9055, "Type": 0x60C, "Index": 49, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 9056, "Type": 0x60C, "Index": 48, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 10001, "Type": 0x60D, "Index": 7, "Line": "0", "LT": "Object_ID", "LB": "msb", "Color": "#84ff42" },
    //     { "Id": 10002, "Type": 0x60D, "Index": 6, "Line": "6", "LT": "", "LB": "", "Color": "#84ff42" },
    //     { "Id": 10003, "Type": 0x60D, "Index": 5, "Line": "6", "LT": "", "LB": "", "Color": "#84ff42" },
    //     { "Id": 10004, "Type": 0x60D, "Index": 4, "Line": "6", "LT": "", "LB": "", "Color": "#84ff42" },
    //     { "Id": 10005, "Type": 0x60D, "Index": 3, "Line": "6", "LT": "", "LB": "", "Color": "#84ff42" },
    //     { "Id": 10006, "Type": 0x60D, "Index": 2, "Line": "6", "LT": "", "LB": "", "Color": "#84ff42" },
    //     { "Id": 10007, "Type": 0x60D, "Index": 1, "Line": "6", "LT": "", "LB": "", "Color": "#84ff42" },
    //     { "Id": 10008, "Type": 0x60D, "Index": 0, "Line": "8", "LT": "", "LB": "lsb", "Color": "#84ff42" },
    //     { "Id": 10009, "Type": 0x60D, "Index": 15, "Line": "0", "LT": "Object_ArelLong", "LB": "msb", "Color": "#4284c4" },
    //     { "Id": 10010, "Type": 0x60D, "Index": 14, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 10011, "Type": 0x60D, "Index": 13, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 10012, "Type": 0x60D, "Index": 12, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 10013, "Type": 0x60D, "Index": 11, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 10014, "Type": 0x60D, "Index": 10, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 10015, "Type": 0x60D, "Index": 9, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 10016, "Type": 0x60D, "Index": 8, "Line": "7", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 10017, "Type": 0x60D, "Index": 23, "Line": "3", "LT": "Object_ArelLong", "LB": "", "Color": "#4284c4" },
    //     { "Id": 10018, "Type": 0x60D, "Index": 22, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 10019, "Type": 0x60D, "Index": 21, "Line": "8", "LT": "", "LB": "lsb", "Color": "#4284c4" },
    //     { "Id": 10020, "Type": 0x60D, "Index": 20, "Line": "0", "LT": "Object_ArelLat", "LB": "msb", "Color": "#84c442" },
    //     { "Id": 10021, "Type": 0x60D, "Index": 19, "Line": "6", "LT": "", "LB": "", "Color": "#84c442" },
    //     { "Id": 10022, "Type": 0x60D, "Index": 18, "Line": "6", "LT": "", "LB": "", "Color": "#84c442" },
    //     { "Id": 10023, "Type": 0x60D, "Index": 17, "Line": "6", "LT": "", "LB": "", "Color": "#84c442" },
    //     { "Id": 10024, "Type": 0x60D, "Index": 16, "Line": "7", "LT": "", "LB": "", "Color": "#84c442" },
    //     { "Id": 10025, "Type": 0x60D, "Index": 31, "Line": "3", "LT": "Object_ArelLat", "LB": "", "Color": "#84c442" },
    //     { "Id": 10026, "Type": 0x60D, "Index": 30, "Line": "6", "LT": "", "LB": "", "Color": "#84c442" },
    //     { "Id": 10027, "Type": 0x60D, "Index": 29, "Line": "6", "LT": "", "LB": "", "Color": "#84c442" },
    //     { "Id": 10028, "Type": 0x60D, "Index": 28, "Line": "8", "LT": "", "LB": "lsb", "Color": "#84c442" },
    //     { "Id": 10029, "Type": 0x60D, "Index": 27, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 10030, "Type": 0x60D, "Index": 26, "Line": "0", "LT": "Object_Class", "LB": "msb", "Color": "#ff8442" },
    //     { "Id": 10031, "Type": 0x60D, "Index": 25, "Line": "6", "LT": "", "LB": "", "Color": "#ff8442" },
    //     { "Id": 10032, "Type": 0x60D, "Index": 24, "Line": "8", "LT": "", "LB": "lsb", "Color": "#ff8442" },
    //     { "Id": 10033, "Type": 0x60D, "Index": 39, "Line": "0", "LT": "Object_OrientationAngel", "LB": "msb", "Color": "#ff84c4" },
    //     { "Id": 10034, "Type": 0x60D, "Index": 38, "Line": "6", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 10035, "Type": 0x60D, "Index": 37, "Line": "6", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 10036, "Type": 0x60D, "Index": 36, "Line": "6", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 10037, "Type": 0x60D, "Index": 35, "Line": "6", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 10038, "Type": 0x60D, "Index": 34, "Line": "6", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 10039, "Type": 0x60D, "Index": 33, "Line": "6", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 10040, "Type": 0x60D, "Index": 32, "Line": "3", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 10041, "Type": 0x60D, "Index": 47, "Line": "7", "LT": "Object_OrientationAngel", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 10042, "Type": 0x60D, "Index": 46, "Line": "8", "LT": "", "LB": "lsb", "Color": "#ff84c4" },
    //     { "Id": 10043, "Type": 0x60D, "Index": 45, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 10044, "Type": 0x60D, "Index": 44, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 10045, "Type": 0x60D, "Index": 43, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 10046, "Type": 0x60D, "Index": 42, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 10047, "Type": 0x60D, "Index": 41, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 10048, "Type": 0x60D, "Index": 40, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 10049, "Type": 0x60D, "Index": 55, "Line": "0", "LT": "Object_Length", "LB": "msb", "Color": "#ffc484" },
    //     { "Id": 10050, "Type": 0x60D, "Index": 54, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 10051, "Type": 0x60D, "Index": 53, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 10052, "Type": 0x60D, "Index": 52, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 10053, "Type": 0x60D, "Index": 51, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 10054, "Type": 0x60D, "Index": 50, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 10055, "Type": 0x60D, "Index": 49, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 10056, "Type": 0x60D, "Index": 48, "Line": "8", "LT": "", "LB": "lsb", "Color": "#ffc484" },
    //     { "Id": 10057, "Type": 0x60D, "Index": 63, "Line": "0", "LT": "Object_Width", "LB": "msb", "Color": "#42ff84" },
    //     { "Id": 10058, "Type": 0x60D, "Index": 62, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 10059, "Type": 0x60D, "Index": 61, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 10060, "Type": 0x60D, "Index": 60, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 10061, "Type": 0x60D, "Index": 59, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 10062, "Type": 0x60D, "Index": 58, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 10063, "Type": 0x60D, "Index": 57, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 10064, "Type": 0x60D, "Index": 56, "Line": "8", "LT": "", "LB": "lsb", "Color": "#42ff84" },
    //     { "Id": 11001, "Type": 0x60E, "Index": 7, "Line": "0", "LT": "Object_ID", "LB": "msb", "Color": "#4284c4" },
    //     { "Id": 11002, "Type": 0x60E, "Index": 6, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 11003, "Type": 0x60E, "Index": 5, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 11004, "Type": 0x60E, "Index": 4, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 11005, "Type": 0x60E, "Index": 3, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 11006, "Type": 0x60E, "Index": 2, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 11007, "Type": 0x60E, "Index": 1, "Line": "6", "LT": "", "LB": "", "Color": "#4284c4" },
    //     { "Id": 11008, "Type": 0x60E, "Index": 0, "Line": "8", "LT": "", "LB": "lsb", "Color": "#4284c4" },
    //     { "Id": 11009, "Type": 0x60E, "Index": 15, "Line": "0", "LT": "Object_CollDetRegionBitfield", "LB": "msb", "Color": "#ffc484" },
    //     { "Id": 11010, "Type": 0x60E, "Index": 14, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 11011, "Type": 0x60E, "Index": 13, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 11012, "Type": 0x60E, "Index": 12, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 11013, "Type": 0x60E, "Index": 11, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 11014, "Type": 0x60E, "Index": 10, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 11015, "Type": 0x60E, "Index": 9, "Line": "6", "LT": "", "LB": "", "Color": "#ffc484" },
    //     { "Id": 11016, "Type": 0x60E, "Index": 8, "Line": "8", "LT": "", "LB": "lsb", "Color": "#ffc484" },
    //     { "Id": 11017, "Type": 0x60E, "Index": 23, "Line": "0", "LT": "Reserved", "LB": "msb", "Color": "#42ff84" },
    //     { "Id": 11018, "Type": 0x60E, "Index": 22, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 11019, "Type": 0x60E, "Index": 21, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 11020, "Type": 0x60E, "Index": 20, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 11021, "Type": 0x60E, "Index": 19, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 11022, "Type": 0x60E, "Index": 18, "Line": "6", "LT": "", "LB": "", "Color": "#42ff84" },
    //     { "Id": 11023, "Type": 0x60E, "Index": 17, "Line": "8", "LT": "", "LB": "lsb", "Color": "#42ff84" },
    //     { "Id": 11024, "Type": 0x60E, "Index": 16, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 11025, "Type": 0x60E, "Index": 31, "Line": "0", "LT": "Reserved", "LB": "msb", "Color": "#ff84c4" },
    //     { "Id": 11026, "Type": 0x60E, "Index": 30, "Line": "6", "LT": "", "LB": "", "Color": "#ff84c4" },
    //     { "Id": 11027, "Type": 0x60E, "Index": 29, "Line": "8", "LT": "", "LB": "lsb", "Color": "#ff84c4" },
    //     { "Id": 11028, "Type": 0x60E, "Index": 28, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 11029, "Type": 0x60E, "Index": 27, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 11030, "Type": 0x60E, "Index": 26, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 11031, "Type": 0x60E, "Index": 25, "Line": "", "LT": "", "LB": "", "Color": "" },
    //     { "Id": 11032, "Type": 0x60E, "Index": 24, "Line": "", "LT": "", "LB": "", "Color": "" },
    // ];

    // public TypeMap: Map<number, string> = new Map([
    //     [-1, '无'],
    //     [0, '全部'],
    //     [0x201, '0x201'],
    //     [0x402, '0x402'],
    //     [0x408, '0x408'],
    //     [0x700, '0x700'],
    //     [0x60A, '0x60A'],
    //     [0x60B, '0x60B'],
    //     [0x60C, '0x60C'],
    //     [0x60D, '0x60D'],
    //     [0x60E, '0x60E'],
    // ]);

    public Capacity: number = 64;

    /**
     * 协议类型
     */
    public Type: Ref<number> = ref(-1);

    public Datas: UnwrapNestedRefs<Array<Uint8Array>> = reactive([]);
    public FrameIndex: number = 0;
    public DataType: Ref<number> = ref(-1);
    public DataBits: Ref<Array<number>> = ref([]);

    public DocumentUrl: Ref<string> = ref('/static/Lidar/协议解析.pdf');

    public ShowDocument: Ref<boolean> = ref(false);
    public ShowTool: Ref<boolean> = ref(false);
    

    public DataSource: Ref<string> = ref('Device');

    public SimulatedData: Array<Uint8Array> = [
        new Uint8Array([0x55,0xAA,0x05,0x5A,0x00,0x01,0x00,0x00,0xFF,0x02,0x05,0x08,0x00,0x7C,0x21,0x28,0x02,0x01,0x0D,0x1A,0x00,0x00,0x58,0x68,0x5B,0xBC,0x00,0x08,0xE9,0x78,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0xB5,0x1B,0x00,0x00,0xFF,0xEE,0x74,0x74,0x03,0xFE,0x4B,0x03,0xF7,0x4A,0x03,0xF6,0x4F,0x03,0xE8,0x4C,0x03,0xEA,0x4F,0x03,0xE0,0x4A,0x03,0xE4,0x50,0x03,0xD9,0x40,0x01,0x14,0x04,0x03,0xD1,0x20,0x00,0xFD,0x07,0x01,0x37,0x08,0x00,0x00,0x00,0x00,0xA4,0x0B,0x01,0xB6,0x04,0x00,0x79,0x0E,0x03,0xFF,0x4C,0x03,0xF9,0x4C,0x03,0xF6,0x4F,0x03,0xE7,0x4C,0x03,0xEC,0x4F,0x03,0xE0,0x3F,0x03,0xE6,0x4F,0x03,0xD9,0x4D,0x01,0x10,0x04,0x03,0xCF,0x2D,0x01,0x00,0x07,0x00,0x00,0x00,0x00,0xE9,0x03,0x00,0xA6,0x0B,0x01,0xB9,0x04,0x00,0x75,0x10,0xFF,0xEE,0x74,0x9D,0x03,0xFF,0x4D,0x03,0xF7,0x4B,0x03,0xF7,0x4F,0x03,0xE8,0x4D,0x03,0xEB,0x51,0x03,0xDB,0x35,0x03,0xE7,0x51,0x03,0xD9,0x4F,0x01,0x10,0x04,0x03,0xC8,0x2B,0x00,0xFA,0x08,0x00,0x00,0x00,0x00,0xEE,0x03,0x00,0xA6,0x0B,0x01,0xB7,0x04,0x00,0x76,0x10,0x04,0x00,0x4B,0x03,0xF8,0x4B,0x03,0xF7,0x4F,0x03,0xE8,0x4C,0x03,0xEC,0x51,0x03,0xD9,0x1D,0x03,0xE7,0x50,0x03,0xDA,0x4D,0x01,0x07,0x04,0x03,0xCD,0x2B,0x00,0xF8,0x08,0x00,0x00,0x00,0x00,0xEF,0x03,0x00,0xAF,0x0B,0x01,0xB9,0x03,0x00,0x78,0x11,0xFF,0xEE,0x74,0xC4,0x04,0x00,0x4C,0x03,0xF7,0x4B,0x03,0xF8,0x4F,0x03,0xE8,0x4C,0x03,0xEE,0x4F,0x03,0xD3,0x0D,0x03,0xE7,0x51,0x03,0xDA,0x4D,0x01,0x06,0x04,0x03,0xD4,0x38,0x00,0xF7,0x08,0x00,0x00,0x00,0x00,0xE3,0x02,0x00,0xB3,0x0B,0x01,0xAB,0x03,0x00,0x76,0x10,0x04,0x02,0x4D,0x03,0xF9,0x4B,0x03,0xF8,0x4F,0x03,0xEA,0x4C,0x03,0xED,0x51,0x03,0xD6,0x0D,0x03,0xEA,0x51,0x03,0xD9,0x4D,0x01,0x05,0x04,0x03,0xD3,0x4F,0x00,0xF4,0x08,0x00,0x00,0x00,0x00,0xDF,0x02,0x00,0xBC,0x0C,0x01,0x9F,0x03,0x00,0x7B,0x0D,0xFF,0xEE,0x74,0xED,0x04,0x02,0x4D,0x03,0xF9,0x4A,0x03,0xF9,0x4F,0x03,0xE8,0x4B,0x03,0xF0,0x53,0x03,0xCF,0x0E,0x03,0xE9,0x51,0x03,0xD9,0x4F,0x01,0x04,0x04,0x03,0xD8,0x55,0x00,0xF1,0x08,0x00,0x00,0x00,0x00,0xE3,0x02,0x00,0xC1,0x0B,0x01,0x9F,0x03,0x00,0x7C,0x0D,0x04,0x04,0x50,0x03,0xF9,0x4B,0x03,0xF9,0x50,0x03,0xE8,0x48,0x03,0xF1,0x51,0x03,0xD0,0x10,0x03,0xEB,0x51,0x03,0xDB,0x4D,0x00,0xFB,0x04,0x03,0xD9,0x55,0x00,0xEC,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBE,0x0B,0x00,0x00,0x00,0x00,0x7F,0x0D,0xFF,0xEE,0x75,0x14,0x04,0x04,0x4F,0x03,0xFA,0x4B,0x03,0xF9,0x50,0x03,0xE7,0x47,0x03,0xF0,0x53,0x03,0xD0,0x0D,0x03,0xEA,0x51,0x03,0xDB,0x4D,0x00,0xF8,0x04,0x03,0xD7,0x57,0x00,0xEB,0x07,0x00,0x00,0x00,0x00,0xBF,0x02,0x00,0xBA,0x0B,0x00,0x00,0x00,0x00,0x7B,0x0C,0x04,0x06,0x4F,0x03,0xF9,0x4B,0x03,0xFA,0x50,0x03,0xE8,0x47,0x03,0xEF,0x51,0x03,0xD1,0x09,0x03,0xED,0x51,0x03,0xDB,0x4D,0x00,0xF0,0x04,0x03,0xD9,0x5A,0x00,0xE9,0x07,0x00,0x00,0x00,0x00,0xC4,0x02,0x00,0xB0,0x08,0x00,0x00,0x00,0x00,0x7A,0x0B,0xFF,0xEE,0x75,0x3D,0x04,0x06,0x4D,0x03,0xF9,0x4A,0x03,0xFA,0x50,0x03,0xE9,0x47,0x03,0xF2,0x50,0x03,0xD1,0x0B,0x03,0xED,0x51,0x03,0xDB,0x4D,0x00,0xEB,0x03,0x03,0xDA,0x5A,0x00,0xEB,0x07,0x00,0x00,0x00,0x00,0xB5,0x02,0x00,0xB2,0x07,0x00,0xF8,0x02,0x00,0x79,0x0B,0x04,0x06,0x4B,0x03,0xF8,0x4B,0x03,0xFA,0x51,0x03,0xE8,0x48,0x03,0xF1,0x51,0x03,0xD1,0x2E,0x03,0xED,0x51,0x03,0xDA,0x4F,0x00,0xE5,0x04,0x03,0xDA,0x5A,0x00,0xE4,0x07,0x00,0x00,0x00,0x00,0xB8,0x02,0x00,0x00,0x00,0x00,0xFC,0x03,0x00,0x78,0x08,0xFF,0xEE,0x75,0x64,0x04,0x07,0x4D,0x03,0xF9,0x4B,0x03,0xFA,0x50,0x03,0xE9,0x48,0x03,0xF2,0x51,0x03,0xD0,0x2D,0x03,0xED,0x51,0x03,0xD9,0x50,0x00,0xE4,0x04,0x03,0xD9,0x48,0x00,0xE4,0x07,0x01,0xF3,0x04,0x00,0xBC,0x02,0x00,0x00,0x00,0x00,0xF6,0x02,0x00,0x7A,0x08,0x04,0x07,0x4F,0x03,0xFA,0x4B,0x03,0xFB,0x50,0x03,0xE9,0x4C,0x03,0xF2,0x50,0x03,0xD2,0x29,0x03,0xED,0x53,0x03,0xDA,0x4C,0x00,0xE3,0x04,0x03,0xD9,0x51,0x00,0xDC,0x04,0x01,0xFD,0x07,0x00,0xBA,0x02,0x00,0x00,0x00,0x00,0xF2,0x02,0x00,0x77,0x08,0xFF,0xEE,0x75,0x8C,0x04,0x09,0x4F,0x03,0xF9,0x4B,0x03,0xFC,0x4F,0x03,0xE9,0x4C,0x03,0xF5,0x51,0x03,0xD4,0x25,0x03,0xED,0x53,0x03,0xDB,0x4F,0x00,0xE5,0x04,0x03,0xCE,0x0C,0x00,0xDE,0x03,0x00,0x00,0x00,0x00,0xC0,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x73,0x07,0x04,0x0A,0x4D,0x03,0xFB,0x4B,0x03,0xFD,0x4F,0x03,0xE9,0x4D,0x03,0xF5,0x53,0x03,0xD6,0x27,0x03,0xEE,0x51,0x03,0xDB,0x4D,0x00,0xE1,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB9,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x79,0x08,0xFF,0xEE,0x75,0xB5,0x04,0x0A,0x4C,0x03,0xF9,0x4A,0x03,0xFE,0x50,0x03,0xEA,0x4D,0x03,0xF4,0x51,0x03,0xDD,0x3E,0x03,0xEE,0x53,0x03,0xDB,0x4D,0x00,0xDE,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBD,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x0C,0x4D,0x03,0xF9,0x4B,0x03,0xFF,0x4F,0x03,0xEA,0x4C,0x03,0xF4,0x51,0x03,0xDB,0x4F,0x03,0xF0,0x51,0x03,0xDB,0x4D,0x00,0xDE,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBF,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xEE,0x75,0xDC,0x04,0x0C,0x4D,0x03,0xF9,0x4A,0x04,0x01,0x4D,0x03,0xE9,0x4C,0x03,0xF7,0x53,0x03,0xDF,0x4C,0x03,0xEF,0x51,0x03,0xDB,0x4C,0x00,0xDB,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x0E,0x4C,0x03,0xFA,0x4B,0x04,0x01,0x4D,0x03,0xEA,0x4C,0x03,0xF6,0x50,0x03,0xE3,0x4F,0x03,0xF1,0x51,0x03,0xDC,0x4C,0x00,0xD8,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xEE,0x76,0x01,0x04,0x0D,0x4B,0x03,0xFA,0x4A,0x04,0x02,0x4D,0x03,0xE9,0x4C,0x03,0xF6,0x51,0x03,0xE2,0x4C,0x03,0xF1,0x50,0x03,0xDD,0x4C,0x00,0xD3,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBA,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x10,0x4C,0x03,0xFC,0x4A,0x04,0x04,0x4C,0x03,0xEA,0x4C,0x03,0xF9,0x50,0x03,0xE3,0x4C,0x03,0xF2,0x50,0x03,0xDC,0x4C,0x00,0xD3,0x03,0x00,0x00,0x00,0x00,0xC5,0x03,0x00,0x00,0x00,0x00,0xB6,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xEE,0x76,0x29,0x04,0x11,0x4A,0x03,0xFB,0x4B,0x04,0x04,0x4D,0x03,0xEC,0x4C,0x03,0xFA,0x50,0x03,0xE3,0x4C,0x03,0xF4,0x4F,0x03,0xDC,0x4C,0x00,0xD1,0x03,0x03,0xDA,0x4F,0x00,0xBB,0x03,0x00,0x00,0x00,0x00,0xB4,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xF0,0x04,0x04,0x11,0x4A,0x03,0xFC,0x4A,0x04,0x05,0x4D,0x03,0xEC,0x4C,0x03,0xFC,0x4D,0x03,0xE2,0x4C,0x03,0xF5,0x4F,0x03,0xDD,0x4C,0x00,0xD0,0x03,0x03,0xDB,0x51,0x00,0xBD,0x03,0x00,0x00,0x00,0x00,0xAE,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xF6,0x04,0x00,0x00,0x00,0x00,0x00,0xFF]),
        new Uint8Array([0x55,0xAA,0x05,0x5A,0x00,0x01,0x00,0x00,0x4F,0x52,0x55,0x58,0x00,0x7C,0x2C,0xD6,0x02,0x01,0x06,0x89,0x00,0x00,0x58,0x68,0x5B,0xBE,0x00,0x08,0xCF,0x80,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0xAC,0x1B,0x00,0x00,0xFF,0xEE,0x6B,0x14,0x04,0x0C,0x55,0x04,0x58,0x46,0x04,0x01,0x55,0x04,0x47,0x42,0x03,0xF5,0x53,0x04,0x3E,0x44,0x01,0xF5,0x07,0x04,0x38,0x3E,0x01,0xF0,0x08,0x02,0x19,0x07,0x01,0xEA,0x04,0x02,0x18,0x07,0x00,0xAD,0x04,0x00,0x85,0x03,0x00,0xB1,0x04,0x00,0x8C,0x04,0x04,0x09,0x53,0x04,0x57,0x46,0x04,0x02,0x55,0x04,0x44,0x42,0x03,0xF6,0x54,0x04,0x3C,0x44,0x01,0xF4,0x07,0x04,0x37,0x3F,0x01,0xED,0x09,0x02,0x1A,0x03,0x01,0xE8,0x07,0x02,0x17,0x04,0x00,0xAC,0x04,0x00,0x86,0x03,0x00,0xB3,0x04,0x00,0x8A,0x04,0xFF,0xEE,0x6B,0x3D,0x04,0x09,0x55,0x04,0x56,0x46,0x04,0x00,0x55,0x04,0x44,0x42,0x03,0xF4,0x54,0x04,0x39,0x44,0x01,0xF7,0x07,0x04,0x35,0x3E,0x01,0xEF,0x09,0x02,0x19,0x03,0x01,0xE7,0x04,0x02,0x18,0x04,0x00,0xAF,0x04,0x00,0x8C,0x04,0x00,0xB2,0x04,0x00,0x8D,0x04,0x04,0x0A,0x53,0x04,0x54,0x46,0x03,0xFF,0x55,0x04,0x42,0x44,0x03,0xF5,0x53,0x04,0x37,0x44,0x01,0xF2,0x07,0x04,0x33,0x40,0x01,0xEA,0x09,0x02,0x1B,0x03,0x01,0xE0,0x07,0x02,0x15,0x07,0x00,0xAE,0x04,0x00,0x83,0x04,0x00,0xB3,0x04,0x00,0x8C,0x04,0xFF,0xEE,0x6B,0x64,0x04,0x09,0x53,0x04,0x52,0x44,0x03,0xFD,0x55,0x04,0x42,0x44,0x03,0xF5,0x54,0x04,0x36,0x46,0x01,0xF2,0x07,0x04,0x2F,0x3E,0x01,0xED,0x09,0x02,0x19,0x03,0x01,0xE3,0x04,0x02,0x16,0x07,0x00,0xAF,0x04,0x00,0x85,0x04,0x00,0xB3,0x04,0x00,0x8A,0x04,0x04,0x05,0x54,0x04,0x51,0x46,0x03,0xFB,0x54,0x04,0x40,0x46,0x03,0xF4,0x54,0x04,0x34,0x46,0x01,0xF0,0x08,0x04,0x2D,0x40,0x01,0xEF,0x0B,0x02,0x17,0x03,0x01,0xE3,0x04,0x02,0x16,0x07,0x00,0xB2,0x04,0x00,0x82,0x07,0x00,0xB6,0x07,0x00,0x8D,0x04,0xFF,0xEE,0x6B,0x8C,0x04,0x06,0x55,0x04,0x4E,0x46,0x03,0xFC,0x55,0x04,0x3C,0x44,0x03,0xF3,0x54,0x04,0x33,0x46,0x01,0xF5,0x07,0x04,0x2E,0x40,0x01,0xEB,0x0B,0x02,0x17,0x03,0x01,0xE2,0x04,0x02,0x16,0x04,0x00,0xAF,0x04,0x00,0x88,0x07,0x00,0xB7,0x04,0x00,0x8F,0x04,0x04,0x06,0x54,0x04,0x4E,0x46,0x03,0xFB,0x53,0x04,0x3B,0x46,0x03,0xF1,0x4B,0x04,0x31,0x46,0x01,0xF5,0x08,0x04,0x2C,0x40,0x01,0xED,0x0B,0x02,0x18,0x03,0x00,0x00,0x00,0x02,0x13,0x07,0x00,0xB2,0x04,0x00,0x86,0x07,0x00,0xB8,0x07,0x00,0x93,0x04,0xFF,0xEE,0x6B,0xB5,0x04,0x04,0x54,0x04,0x4D,0x46,0x03,0xFC,0x57,0x04,0x3A,0x46,0x03,0xED,0x19,0x04,0x2F,0x46,0x01,0xF6,0x07,0x04,0x2C,0x44,0x01,0xEC,0x0B,0x02,0x13,0x03,0x00,0x00,0x00,0x02,0x16,0x04,0x00,0xB4,0x04,0x00,0x88,0x07,0x00,0xBA,0x04,0x00,0x92,0x04,0x04,0x04,0x53,0x04,0x4B,0x46,0x03,0xFC,0x57,0x04,0x38,0x48,0x00,0x00,0x00,0x04,0x2F,0x48,0x01,0xF2,0x07,0x04,0x28,0x43,0x01,0xEC,0x0B,0x02,0x16,0x03,0x00,0x00,0x00,0x02,0x15,0x04,0x00,0xB3,0x04,0x00,0x87,0x07,0x00,0xBE,0x04,0x00,0x92,0x04,0xFF,0xEE,0x6B,0xDC,0x04,0x04,0x53,0x04,0x48,0x46,0x03,0xFB,0x57,0x04,0x38,0x48,0x00,0x00,0x00,0x04,0x2B,0x47,0x01,0xF4,0x07,0x04,0x27,0x46,0x01,0xE8,0x0B,0x02,0x12,0x03,0x00,0x00,0x04,0x02,0x15,0x04,0x00,0xB5,0x04,0x00,0x8A,0x07,0x00,0xBD,0x04,0x00,0x90,0x04,0x04,0x02,0x53,0x04,0x48,0x46,0x03,0xFA,0x57,0x04,0x35,0x47,0x00,0x00,0x00,0x04,0x2A,0x47,0x01,0xF1,0x08,0x04,0x24,0x46,0x01,0xEA,0x0B,0x02,0x14,0x03,0x00,0x00,0x04,0x02,0x12,0x04,0x00,0xB3,0x04,0x00,0x89,0x07,0x00,0xBD,0x04,0x00,0x94,0x04,0xFF,0xEE,0x6C,0x05,0x04,0x01,0x54,0x04,0x44,0x46,0x03,0xFA,0x55,0x04,0x33,0x47,0x00,0x00,0x00,0x04,0x2A,0x48,0x01,0xF4,0x07,0x04,0x25,0x44,0x01,0xE6,0x0C,0x02,0x11,0x03,0x00,0x00,0x04,0x02,0x11,0x04,0x00,0xB5,0x04,0x00,0x8E,0x07,0x00,0xBA,0x04,0x00,0x95,0x04,0x04,0x01,0x54,0x04,0x45,0x46,0x03,0xF8,0x54,0x04,0x32,0x48,0x00,0x00,0x00,0x04,0x28,0x48,0x01,0xF2,0x08,0x04,0x21,0x40,0x01,0xE4,0x0C,0x02,0x11,0x03,0x00,0x00,0x07,0x02,0x0D,0x04,0x00,0xB2,0x04,0x00,0x8B,0x04,0x00,0xBB,0x07,0x00,0x97,0x04,0xFF,0xEE,0x6C,0x2C,0x04,0x00,0x57,0x04,0x42,0x46,0x03,0xF8,0x55,0x04,0x30,0x48,0x00,0x00,0x00,0x04,0x27,0x48,0x01,0xF0,0x07,0x04,0x22,0x3A,0x01,0xE6,0x15,0x02,0x11,0x04,0x00,0x00,0x00,0x02,0x0C,0x04,0x00,0xB7,0x04,0x00,0x8D,0x07,0x00,0xBF,0x07,0x00,0x93,0x04,0x04,0x00,0x54,0x04,0x41,0x46,0x03,0xF9,0x57,0x04,0x2E,0x48,0x03,0xEE,0x4F,0x04,0x23,0x48,0x01,0xF2,0x08,0x04,0x20,0x3B,0x01,0xE2,0x2E,0x02,0x12,0x03,0x00,0x00,0x00,0x02,0x0B,0x04,0x00,0xB5,0x04,0x00,0x8C,0x04,0x00,0xBC,0x04,0x00,0x93,0x04,0xFF,0xEE,0x6C,0x55,0x04,0x00,0x57,0x04,0x3E,0x48,0x03,0xF8,0x57,0x04,0x2D,0x4A,0x03,0xEC,0x4D,0x04,0x22,0x48,0x01,0xEF,0x08,0x04,0x1E,0x3B,0x01,0xE4,0x5A,0x02,0x0F,0x03,0x00,0xB1,0x04,0x02,0x0C,0x04,0x00,0xB9,0x03,0x00,0x8D,0x07,0x00,0xC2,0x04,0x00,0x91,0x04,0x04,0x01,0x57,0x04,0x3E,0x48,0x03,0xF7,0x55,0x04,0x2A,0x4A,0x03,0xEB,0x54,0x04,0x22,0x4C,0x01,0xF0,0x07,0x04,0x1A,0x3C,0x01,0xE3,0x64,0x02,0x11,0x03,0x00,0xB1,0x04,0x02,0x08,0x04,0x00,0xBA,0x04,0x00,0x8E,0x07,0x00,0xC4,0x04,0x00,0x96,0x04,0xFF,0xEE,0x6C,0x7C,0x03,0xFF,0x54,0x04,0x3C,0x47,0x03,0xF7,0x57,0x04,0x29,0x4A,0x03,0xEB,0x53,0x04,0x20,0x4B,0x01,0xEE,0x08,0x04,0x1C,0x3E,0x01,0xDD,0x62,0x02,0x0E,0x03,0x00,0xB0,0x04,0x02,0x0B,0x04,0x00,0xBC,0x04,0x00,0x8E,0x07,0x00,0xC5,0x04,0x00,0x95,0x04,0x03,0xFF,0x57,0x04,0x3B,0x47,0x03,0xF4,0x57,0x04,0x29,0x4A,0x03,0xE9,0x55,0x04,0x1F,0x4C,0x01,0xEF,0x08,0x04,0x1A,0x3F,0x01,0xE1,0x27,0x02,0x0D,0x03,0x00,0xB6,0x07,0x02,0x0C,0x04,0x00,0xBB,0x03,0x00,0x8E,0x07,0x00,0xC7,0x04,0x00,0x96,0x04,0xFF,0xEE,0x6C,0xA6,0x03,0xFE,0x54,0x04,0x38,0x47,0x03,0xF5,0x57,0x04,0x26,0x4A,0x03,0xE9,0x54,0x04,0x1F,0x4C,0x01,0xED,0x08,0x04,0x18,0x3F,0x01,0xE1,0x0B,0x02,0x0F,0x03,0x00,0xB1,0x07,0x02,0x0B,0x04,0x00,0xBE,0x03,0x00,0x8F,0x07,0x00,0xC6,0x04,0x00,0x99,0x04,0x03,0xFE,0x54,0x04,0x38,0x48,0x03,0xF5,0x57,0x04,0x27,0x4A,0x03,0xE9,0x54,0x04,0x1C,0x4C,0x01,0xF5,0x08,0x04,0x17,0x40,0x00,0x00,0x00,0x02,0x0B,0x03,0x00,0xB0,0x07,0x02,0x09,0x04,0x00,0xBD,0x03,0x00,0x91,0x07,0x00,0xCA,0x04,0x00,0x96,0x04,0xFF,0xEE,0x6C,0xCE,0x03,0xFC,0x54,0x04,0x37,0x48,0x03,0xF3,0x57,0x04,0x25,0x4B,0x03,0xE7,0x54,0x04,0x1B,0x4C,0x01,0xF2,0x08,0x04,0x16,0x40,0x00,0x00,0x00,0x02,0x0C,0x03,0x00,0xB4,0x07,0x02,0x0B,0x04,0x00,0xBE,0x03,0x00,0x90,0x07,0x00,0xCD,0x04,0x00,0x98,0x04,0x03,0xFC,0x54,0x04,0x34,0x4A,0x03,0xF4,0x57,0x04,0x24,0x4B,0x03,0xE7,0x55,0x04,0x1B,0x4C,0x01,0xEE,0x08,0x04,0x14,0x42,0x00,0x00,0x00,0x02,0x07,0x03,0x00,0xB8,0x07,0x02,0x09,0x04,0x00,0xBE,0x03,0x00,0x94,0x07,0x00,0xCA,0x04,0x00,0x98,0x04,0x00,0x00,0x00,0x00,0x00,0xFF]),
        new Uint8Array([0x55,0xAA,0x05,0x5A,0x00,0x01,0x00,0x00,0x3F,0x42,0x45,0x48,0x00,0x7C,0x44,0x60,0x02,0x01,0x06,0x8E,0x00,0x00,0x58,0x68,0x5B,0xC2,0x00,0x09,0x13,0x37,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0xB5,0x1B,0x00,0x00,0xFF,0xEE,0x83,0x74,0x06,0x00,0x2F,0x05,0x19,0x36,0x05,0xE8,0x31,0x05,0x05,0x36,0x05,0xDA,0x33,0x04,0xFC,0x3C,0x05,0xD4,0x32,0x04,0xF3,0x3E,0x05,0xD9,0x33,0x04,0xF0,0x3E,0x05,0x30,0x22,0x04,0xF4,0x38,0x04,0xB4,0x21,0x04,0x73,0x19,0x04,0xCD,0x1E,0x04,0x8A,0x16,0x06,0x03,0x2F,0x05,0x1C,0x35,0x05,0xF0,0x31,0x05,0x06,0x37,0x05,0xDF,0x32,0x05,0x00,0x3B,0x05,0xDA,0x31,0x04,0xF7,0x3C,0x05,0xDF,0x33,0x04,0xF2,0x3A,0x05,0x2B,0x21,0x04,0xF7,0x38,0x04,0xB9,0x21,0x04,0x71,0x1A,0x04,0xD1,0x1D,0x04,0x84,0x18,0xFF,0xEE,0x83,0x9D,0x06,0x0A,0x2F,0x05,0x20,0x35,0x05,0xF5,0x2F,0x05,0x0D,0x36,0x05,0xE5,0x32,0x05,0x03,0x3B,0x05,0xE1,0x32,0x04,0xFA,0x3B,0x05,0xE7,0x33,0x04,0xFA,0x3E,0x05,0x27,0x21,0x04,0xF9,0x37,0x04,0xBF,0x21,0x04,0x6C,0x1A,0x04,0xD4,0x1E,0x04,0x83,0x12,0x06,0x12,0x2E,0x05,0x22,0x33,0x05,0xF8,0x31,0x05,0x10,0x36,0x05,0xEC,0x32,0x05,0x07,0x3A,0x05,0xE5,0x32,0x04,0xFD,0x3A,0x05,0xEC,0x33,0x04,0xFE,0x3E,0x05,0x22,0x20,0x04,0xFD,0x38,0x04,0xC3,0x21,0x04,0x69,0x1A,0x04,0xDA,0x21,0x04,0x7C,0x0C,0xFF,0xEE,0x83,0xC4,0x06,0x17,0x2E,0x05,0x26,0x33,0x06,0x00,0x2F,0x05,0x13,0x35,0x05,0xF3,0x32,0x05,0x0C,0x3A,0x05,0xEC,0x32,0x05,0x02,0x3A,0x05,0xF2,0x32,0x05,0x00,0x3E,0x05,0x1C,0x1E,0x05,0x01,0x36,0x04,0xC9,0x21,0x04,0x62,0x1A,0x00,0x00,0x00,0x04,0x78,0x09,0x06,0x20,0x2E,0x05,0x2A,0x33,0x06,0x06,0x2F,0x05,0x19,0x35,0x05,0xF8,0x32,0x05,0x0F,0x3A,0x05,0xF2,0x32,0x05,0x07,0x3A,0x05,0xF7,0x32,0x05,0x06,0x3E,0x05,0x16,0x20,0x05,0x06,0x36,0x04,0xCC,0x20,0x04,0x60,0x1C,0x04,0x48,0x01,0x04,0x70,0x09,0xFF,0xEE,0x83,0xED,0x06,0x24,0x2D,0x05,0x30,0x33,0x06,0x0D,0x2E,0x05,0x19,0x33,0x05,0xFD,0x31,0x05,0x14,0x38,0x05,0xF8,0x31,0x05,0x0A,0x38,0x05,0xFE,0x32,0x05,0x0A,0x3E,0x05,0x11,0x1E,0x05,0x08,0x37,0x04,0xD0,0x1D,0x04,0x5B,0x1A,0x00,0x00,0x00,0x04,0x6D,0x0B,0x06,0x2C,0x2D,0x05,0x33,0x33,0x06,0x14,0x2E,0x05,0x20,0x33,0x06,0x05,0x31,0x05,0x1A,0x38,0x05,0xFE,0x31,0x05,0x0E,0x37,0x06,0x06,0x32,0x05,0x0B,0x3B,0x05,0x07,0x1D,0x05,0x0C,0x35,0x04,0xD5,0x1C,0x04,0x56,0x11,0x00,0x00,0x00,0x04,0x68,0x0C,0xFF,0xEE,0x84,0x14,0x06,0x32,0x2D,0x05,0x37,0x33,0x06,0x1B,0x2D,0x05,0x23,0x33,0x06,0x0B,0x31,0x05,0x1C,0x36,0x06,0x05,0x31,0x05,0x11,0x35,0x06,0x0D,0x32,0x05,0x0D,0x38,0x04,0xFF,0x1E,0x05,0x13,0x37,0x04,0xDA,0x1D,0x04,0x50,0x0B,0x00,0x00,0x00,0x04,0x66,0x0D,0x06,0x38,0x2D,0x05,0x3A,0x33,0x06,0x23,0x2D,0x05,0x29,0x33,0x06,0x12,0x31,0x05,0x1E,0x36,0x06,0x0C,0x31,0x05,0x16,0x35,0x06,0x11,0x31,0x05,0x13,0x3B,0x04,0xF9,0x1E,0x05,0x17,0x38,0x04,0xE1,0x1E,0x04,0x4C,0x07,0x04,0xF2,0x03,0x04,0x61,0x10,0xFF,0xEE,0x84,0x3C,0x06,0x3F,0x2B,0x05,0x3D,0x32,0x06,0x29,0x2D,0x05,0x2C,0x33,0x06,0x1A,0x31,0x05,0x23,0x36,0x06,0x12,0x2F,0x05,0x1B,0x35,0x06,0x18,0x32,0x05,0x17,0x3B,0x04,0xF5,0x20,0x05,0x1D,0x3A,0x04,0xE7,0x1C,0x04,0x48,0x08,0x02,0x5D,0x2F,0x04,0x5E,0x14,0x06,0x46,0x2B,0x05,0x42,0x33,0x06,0x32,0x2E,0x05,0x31,0x33,0x06,0x1F,0x2F,0x05,0x26,0x36,0x06,0x18,0x2F,0x05,0x1D,0x35,0x06,0x1F,0x32,0x05,0x1D,0x3C,0x04,0xF7,0x22,0x05,0x22,0x3C,0x04,0xEC,0x1C,0x04,0x45,0x0B,0x02,0x5E,0x3B,0x04,0x57,0x15,0xFF,0xEE,0x84,0x64,0x06,0x4D,0x2D,0x05,0x46,0x32,0x06,0x37,0x2D,0x05,0x32,0x33,0x06,0x27,0x2F,0x05,0x2B,0x35,0x06,0x20,0x2F,0x05,0x22,0x35,0x06,0x25,0x31,0x05,0x1F,0x3B,0x04,0xF5,0x23,0x05,0x24,0x38,0x04,0xF1,0x1D,0x04,0x43,0x0C,0x02,0x60,0x26,0x04,0x55,0x18,0x06,0x56,0x2B,0x05,0x4A,0x32,0x06,0x3E,0x2D,0x05,0x36,0x33,0x06,0x2D,0x2F,0x05,0x30,0x35,0x06,0x28,0x2F,0x05,0x27,0x35,0x06,0x2C,0x31,0x05,0x23,0x3B,0x04,0xF5,0x1A,0x05,0x29,0x3F,0x04,0xF6,0x1D,0x04,0x40,0x0D,0x02,0x5C,0x31,0x04,0x50,0x1A,0xFF,0xEE,0x84,0x8C,0x06,0x5B,0x2A,0x05,0x4E,0x32,0x06,0x43,0x2D,0x05,0x39,0x32,0x06,0x34,0x2F,0x05,0x33,0x36,0x06,0x2D,0x2F,0x05,0x2B,0x35,0x06,0x34,0x2F,0x05,0x26,0x3A,0x04,0xF3,0x19,0x05,0x2E,0x3C,0x04,0xFA,0x1E,0x04,0x39,0x0E,0x02,0x5A,0x3B,0x04,0x4D,0x1D,0x06,0x63,0x2B,0x05,0x55,0x32,0x06,0x4C,0x2B,0x05,0x3E,0x31,0x06,0x3B,0x2F,0x05,0x38,0x36,0x06,0x35,0x2E,0x05,0x2E,0x35,0x06,0x3A,0x2F,0x05,0x2C,0x38,0x04,0xF1,0x16,0x05,0x30,0x3C,0x05,0x02,0x0C,0x04,0x36,0x18,0x02,0x5E,0x54,0x04,0x48,0x1D,0xFF,0xEE,0x84,0xB4,0x06,0x6A,0x2B,0x05,0x59,0x32,0x06,0x52,0x2B,0x05,0x43,0x32,0x06,0x44,0x2F,0x05,0x3B,0x35,0x06,0x3C,0x2E,0x05,0x32,0x35,0x06,0x42,0x2F,0x05,0x2E,0x38,0x05,0x01,0x0B,0x05,0x36,0x3C,0x00,0x00,0x00,0x04,0x31,0x0D,0x02,0x5C,0x57,0x04,0x42,0x1C,0x06,0x72,0x2B,0x05,0x5D,0x31,0x06,0x59,0x2B,0x05,0x48,0x32,0x06,0x4D,0x2E,0x05,0x41,0x35,0x06,0x44,0x2F,0x05,0x37,0x33,0x06,0x4B,0x2F,0x05,0x32,0x38,0x06,0x4B,0x2E,0x05,0x39,0x3A,0x06,0x67,0x31,0x04,0x29,0x0B,0x02,0x5F,0x36,0x04,0x3A,0x0B,0xFF,0xEE,0x84,0xDD,0x06,0x7A,0x2B,0x05,0x61,0x31,0x06,0x63,0x2B,0x05,0x4D,0x32,0x06,0x53,0x2E,0x05,0x44,0x35,0x06,0x4B,0x2E,0x05,0x3C,0x35,0x06,0x4F,0x2F,0x05,0x37,0x38,0x06,0x5E,0x2F,0x05,0x3F,0x3B,0x06,0x6E,0x2F,0x04,0x2B,0x0B,0x02,0x5C,0x5A,0x04,0x38,0x0B,0x06,0x80,0x2A,0x05,0x65,0x31,0x06,0x6A,0x2D,0x05,0x53,0x31,0x06,0x59,0x2E,0x05,0x48,0x35,0x06,0x53,0x2E,0x05,0x3F,0x33,0x06,0x58,0x31,0x05,0x3C,0x3A,0x06,0x63,0x2F,0x05,0x41,0x33,0x06,0x77,0x2F,0x04,0x35,0x0C,0x02,0x5D,0x46,0x04,0x3E,0x0B,0xFF,0xEE,0x85,0x04,0x06,0x88,0x2A,0x05,0x69,0x31,0x06,0x70,0x2D,0x05,0x55,0x31,0x06,0x63,0x2F,0x05,0x4E,0x33,0x06,0x58,0x2D,0x05,0x44,0x33,0x06,0x61,0x2F,0x05,0x3F,0x37,0x06,0x6C,0x2E,0x05,0x48,0x3C,0x06,0x7E,0x2E,0x04,0x36,0x1A,0x02,0x60,0x31,0x04,0x3F,0x14,0x06,0x8F,0x2A,0x05,0x70,0x31,0x06,0x78,0x2B,0x05,0x5D,0x2F,0x06,0x68,0x2E,0x05,0x52,0x33,0x06,0x61,0x2E,0x05,0x48,0x33,0x06,0x67,0x2E,0x05,0x43,0x35,0x06,0x71,0x2E,0x05,0x4A,0x38,0x06,0x85,0x2E,0x04,0x3A,0x1C,0x02,0x60,0x35,0x04,0x48,0x21,0xFF,0xEE,0x85,0x2D,0x06,0x98,0x2A,0x05,0x73,0x31,0x06,0x82,0x2B,0x05,0x5F,0x31,0x06,0x6F,0x2E,0x05,0x57,0x32,0x06,0x69,0x2E,0x05,0x4D,0x32,0x06,0x6E,0x2F,0x05,0x4A,0x35,0x06,0x79,0x2D,0x05,0x50,0x38,0x06,0x8D,0x2E,0x04,0x3D,0x1C,0x02,0x5E,0x60,0x04,0x4A,0x22,0x06,0xA0,0x2B,0x05,0x77,0x31,0x06,0x86,0x2B,0x05,0x65,0x31,0x06,0x77,0x2E,0x05,0x5C,0x32,0x06,0x70,0x2E,0x05,0x50,0x32,0x06,0x76,0x2E,0x05,0x4E,0x35,0x06,0x81,0x2D,0x05,0x54,0x37,0x06,0x95,0x2E,0x04,0x40,0x1E,0x02,0x61,0x65,0x04,0x4E,0x21,0x00,0x00,0x00,0x00,0x00,0xFF]),
        new Uint8Array([0x55,0xAA,0x05,0x5A,0x00,0x01,0x00,0x00,0xDF,0xE2,0xE5,0xE8,0x00,0x7C,0x50,0x3C,0x02,0x01,0x06,0x88,0x00,0x00,0x58,0x68,0x5B,0xC4,0x00,0x09,0x70,0xF2,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0xAF,0x1B,0x00,0x00,0xFF,0xEE,0x18,0x94,0x05,0x68,0x2F,0x06,0xBC,0x20,0x05,0x54,0x2A,0x06,0x9D,0x21,0x05,0x49,0x29,0x06,0x8F,0x21,0x05,0x44,0x27,0x06,0x7F,0x22,0x05,0x48,0x29,0x06,0x7C,0x25,0x05,0x4F,0x27,0x06,0x81,0x22,0x05,0x5C,0x26,0x05,0x6D,0x26,0x05,0x2F,0x12,0x05,0x4C,0x18,0x05,0x64,0x29,0x06,0xB3,0x22,0x05,0x51,0x29,0x06,0x94,0x21,0x05,0x45,0x2A,0x06,0x87,0x21,0x05,0x3E,0x2A,0x06,0x78,0x25,0x05,0x43,0x29,0x06,0x75,0x27,0x05,0x4B,0x2A,0x06,0x7A,0x27,0x05,0x5A,0x2B,0x00,0x00,0x00,0x05,0x38,0x1C,0x05,0x4F,0x18,0xFF,0xEE,0x18,0xBD,0x05,0x5E,0x29,0x06,0xA8,0x21,0x05,0x4B,0x29,0x06,0x8E,0x22,0x05,0x3F,0x29,0x06,0x7D,0x21,0x05,0x3A,0x29,0x06,0x71,0x21,0x05,0x40,0x27,0x06,0x6B,0x22,0x05,0x46,0x29,0x06,0x71,0x23,0x05,0x55,0x29,0x06,0x82,0x22,0x05,0x35,0x1C,0x05,0x53,0x19,0x05,0x5A,0x29,0x06,0xA0,0x22,0x05,0x46,0x29,0x06,0x84,0x22,0x05,0x3C,0x29,0x06,0x76,0x22,0x05,0x35,0x29,0x06,0x69,0x21,0x05,0x3C,0x29,0x06,0x63,0x21,0x05,0x41,0x26,0x06,0x6A,0x23,0x05,0x4E,0x29,0x06,0x7B,0x25,0x05,0x48,0x1A,0x05,0x59,0x1C,0xFF,0xEE,0x18,0xE4,0x05,0x54,0x2A,0x06,0x9A,0x23,0x05,0x44,0x29,0x06,0x7C,0x22,0x05,0x36,0x29,0x06,0x6C,0x22,0x05,0x2F,0x29,0x06,0x5D,0x22,0x05,0x36,0x2B,0x06,0x5C,0x22,0x05,0x3D,0x29,0x06,0x62,0x23,0x05,0x49,0x23,0x06,0x74,0x23,0x05,0x55,0x1D,0x05,0x5A,0x1D,0x05,0x50,0x2A,0x06,0x91,0x26,0x05,0x40,0x29,0x06,0x73,0x26,0x05,0x33,0x2A,0x06,0x62,0x27,0x05,0x2C,0x29,0x06,0x57,0x22,0x05,0x31,0x29,0x06,0x50,0x22,0x05,0x3A,0x29,0x06,0x5A,0x21,0x05,0x43,0x0D,0x06,0x6B,0x23,0x05,0x57,0x23,0x05,0x5D,0x1E,0xFF,0xEE,0x19,0x0D,0x05,0x4F,0x2A,0x06,0x8B,0x22,0x05,0x38,0x29,0x06,0x6C,0x23,0x05,0x2C,0x27,0x06,0x5C,0x22,0x05,0x28,0x29,0x06,0x4E,0x22,0x05,0x2D,0x2A,0x06,0x49,0x22,0x05,0x34,0x29,0x06,0x50,0x21,0x05,0x42,0x0C,0x06,0x62,0x23,0x05,0x50,0x1D,0x05,0x60,0x1E,0x05,0x47,0x29,0x06,0x81,0x21,0x05,0x35,0x2B,0x06,0x63,0x21,0x05,0x2A,0x2D,0x06,0x55,0x22,0x05,0x23,0x2D,0x06,0x49,0x23,0x05,0x28,0x26,0x06,0x42,0x23,0x05,0x30,0x2B,0x06,0x4A,0x23,0x05,0x3A,0x0C,0x06,0x5E,0x23,0x05,0x4A,0x1E,0x05,0x62,0x20,0xFF,0xEE,0x19,0x34,0x05,0x44,0x2A,0x06,0x78,0x22,0x05,0x2E,0x29,0x06,0x5D,0x22,0x05,0x23,0x2B,0x06,0x4E,0x22,0x05,0x1F,0x2B,0x06,0x41,0x23,0x05,0x23,0x2B,0x06,0x3C,0x23,0x05,0x2D,0x2B,0x06,0x42,0x22,0x05,0x36,0x2D,0x06,0x50,0x23,0x05,0x4F,0x27,0x05,0x65,0x21,0x05,0x40,0x2A,0x06,0x6F,0x22,0x05,0x2C,0x2A,0x06,0x55,0x22,0x05,0x1F,0x2B,0x06,0x46,0x23,0x05,0x1C,0x2A,0x06,0x3A,0x23,0x05,0x20,0x2B,0x06,0x34,0x27,0x05,0x28,0x2B,0x06,0x3B,0x25,0x05,0x37,0x2D,0x06,0x47,0x23,0x05,0x4A,0x2A,0x05,0x6A,0x22,0xFF,0xEE,0x19,0x5C,0x05,0x3B,0x2A,0x06,0x68,0x22,0x05,0x26,0x2A,0x06,0x4E,0x22,0x05,0x1B,0x2B,0x06,0x3F,0x23,0x05,0x15,0x2A,0x06,0x31,0x22,0x05,0x1C,0x2A,0x06,0x2D,0x23,0x05,0x24,0x2B,0x06,0x33,0x23,0x05,0x32,0x2D,0x06,0x3F,0x23,0x05,0x46,0x2A,0x05,0x6D,0x23,0x05,0x37,0x2A,0x06,0x61,0x23,0x05,0x22,0x29,0x06,0x46,0x23,0x05,0x17,0x2D,0x06,0x36,0x26,0x05,0x12,0x2A,0x06,0x29,0x23,0x05,0x17,0x2A,0x06,0x25,0x23,0x05,0x20,0x29,0x06,0x2D,0x23,0x05,0x2C,0x2A,0x00,0x00,0x00,0x05,0x42,0x29,0x05,0x6F,0x23,0xFF,0xEE,0x19,0x85,0x05,0x33,0x2A,0x06,0x5A,0x23,0x05,0x1E,0x27,0x06,0x3E,0x22,0x05,0x13,0x2B,0x06,0x2D,0x22,0x05,0x0D,0x2B,0x06,0x21,0x22,0x05,0x14,0x2A,0x06,0x1D,0x25,0x05,0x1A,0x29,0x06,0x26,0x23,0x05,0x29,0x2A,0x05,0x4C,0x22,0x05,0x3E,0x29,0x05,0x48,0x23,0x05,0x2E,0x32,0x06,0x53,0x23,0x05,0x1C,0x2A,0x06,0x35,0x23,0x05,0x0E,0x2B,0x06,0x28,0x29,0x05,0x0A,0x2B,0x06,0x1C,0x27,0x05,0x0F,0x2B,0x06,0x16,0x23,0x05,0x16,0x29,0x06,0x1B,0x23,0x05,0x24,0x2B,0x05,0x4A,0x22,0x05,0x39,0x2A,0x05,0x27,0x2D,0xFF,0xEE,0x19,0xAC,0x05,0x29,0x29,0x06,0x4B,0x23,0x05,0x16,0x2A,0x06,0x2F,0x27,0x05,0x0C,0x2D,0x06,0x21,0x27,0x05,0x06,0x2A,0x06,0x16,0x23,0x05,0x0B,0x2B,0x06,0x0F,0x23,0x05,0x11,0x2A,0x06,0x14,0x23,0x05,0x1F,0x2A,0x05,0x48,0x26,0x05,0x38,0x2A,0x05,0x2C,0x2E,0x05,0x23,0x2B,0x06,0x45,0x23,0x05,0x12,0x2B,0x06,0x28,0x23,0x05,0x07,0x2D,0x06,0x1B,0x26,0x05,0x00,0x2B,0x06,0x0F,0x25,0x05,0x07,0x2D,0x06,0x09,0x25,0x05,0x0C,0x2B,0x06,0x0E,0x23,0x05,0x1A,0x2A,0x05,0x46,0x25,0x05,0x31,0x29,0x05,0x4E,0x33,0xFF,0xEE,0x19,0xD5,0x05,0x20,0x2B,0x06,0x3D,0x23,0x05,0x0E,0x2B,0x06,0x21,0x23,0x05,0x03,0x2A,0x06,0x13,0x23,0x04,0xFB,0x2B,0x06,0x07,0x23,0x05,0x03,0x2D,0x06,0x00,0x23,0x05,0x09,0x2D,0x06,0x08,0x23,0x05,0x17,0x2B,0x05,0x43,0x26,0x05,0x2B,0x29,0x05,0x68,0x44,0x05,0x1C,0x2D,0x06,0x33,0x23,0x05,0x0D,0x2D,0x06,0x1A,0x22,0x04,0xFF,0x2D,0x06,0x0B,0x25,0x04,0xF9,0x2B,0x06,0x00,0x25,0x04,0xFF,0x2D,0x05,0xFB,0x25,0x05,0x05,0x2B,0x06,0x02,0x22,0x05,0x13,0x2B,0x05,0x40,0x25,0x05,0x29,0x29,0x05,0x68,0x43,0xFF,0xEE,0x19,0xFC,0x05,0x19,0x2D,0x06,0x2E,0x25,0x05,0x05,0x29,0x06,0x14,0x25,0x04,0xFB,0x2A,0x06,0x05,0x27,0x04,0xF6,0x2B,0x05,0xF7,0x29,0x04,0xFA,0x2D,0x05,0xF2,0x2A,0x05,0x02,0x2B,0x05,0xFB,0x26,0x05,0x10,0x2B,0x05,0x40,0x26,0x05,0x23,0x26,0x05,0x67,0x40,0x05,0x15,0x2E,0x06,0x28,0x2B,0x05,0x04,0x2B,0x06,0x0D,0x23,0x04,0xF7,0x2F,0x05,0xFD,0x25,0x04,0xF0,0x2D,0x05,0xF2,0x25,0x04,0xF8,0x2D,0x05,0xEE,0x25,0x04,0xFD,0x2B,0x05,0xF4,0x25,0x05,0x0B,0x2D,0x05,0x3D,0x25,0x05,0x22,0x2A,0x05,0x65,0x37,0xFF,0xEE,0x1A,0x25,0x05,0x13,0x2D,0x06,0x22,0x26,0x05,0x01,0x31,0x06,0x05,0x23,0x04,0xF3,0x2D,0x05,0xF8,0x25,0x04,0xEE,0x33,0x05,0xEA,0x25,0x04,0xF3,0x2E,0x05,0xE4,0x25,0x04,0xFA,0x2D,0x05,0xEC,0x25,0x05,0x08,0x33,0x05,0x3A,0x25,0x05,0x1C,0x29,0x05,0x64,0x2D,0x05,0x0D,0x2D,0x06,0x1C,0x25,0x04,0xFE,0x2F,0x06,0x01,0x25,0x04,0xEF,0x2F,0x05,0xF0,0x25,0x04,0xEA,0x2D,0x05,0xE5,0x23,0x04,0xF0,0x2B,0x05,0xDE,0x25,0x04,0xF5,0x2D,0x05,0xE7,0x25,0x05,0x03,0x2B,0x05,0x3D,0x25,0x05,0x18,0x29,0x05,0x61,0x27,0xFF,0xEE,0x1A,0x4C,0x05,0x09,0x2D,0x06,0x14,0x26,0x04,0xFB,0x31,0x05,0xF8,0x23,0x04,0xEB,0x2B,0x05,0xEA,0x26,0x04,0xE6,0x2D,0x05,0xDD,0x23,0x04,0xEC,0x2D,0x05,0xD9,0x26,0x04,0xF2,0x2B,0x05,0xE0,0x23,0x04,0xFF,0x2E,0x05,0x45,0x25,0x05,0x15,0x27,0x05,0x5A,0x1C,0x05,0x07,0x2F,0x06,0x0B,0x27,0x04,0xF6,0x2E,0x05,0xF2,0x26,0x04,0xE7,0x2E,0x05,0xE4,0x25,0x04,0xE1,0x2D,0x05,0xD9,0x23,0x04,0xE8,0x2D,0x05,0xD5,0x29,0x04,0xEF,0x2D,0x05,0xDA,0x23,0x04,0xFC,0x2E,0x05,0x41,0x20,0x05,0x10,0x2D,0x05,0x52,0x19,0x00,0x00,0x00,0x00,0x00,0xFF]),
        new Uint8Array([0x55,0xAA,0x05,0x5A,0x00,0x01,0x00,0x00,0x7F,0x82,0x85,0x88,0x00,0x7C,0x67,0xD8,0x02,0x01,0x06,0x79,0x00,0x00,0x58,0x68,0x5B,0xC8,0x00,0x09,0xE3,0x86,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0xAF,0x1B,0x00,0x00,0xFF,0xEE,0x41,0xD4,0x06,0x48,0x0E,0x02,0x98,0x19,0x06,0x40,0x04,0x02,0x9A,0x20,0x06,0x32,0x03,0x02,0xB6,0x23,0x06,0x2B,0x07,0x01,0x7E,0x03,0x06,0x34,0x04,0x01,0x70,0x20,0x06,0x3D,0x04,0x01,0x6C,0x2E,0x01,0x99,0x14,0x01,0x78,0x16,0x01,0x80,0x63,0x01,0xA5,0x33,0x06,0x47,0x0D,0x02,0x99,0x1D,0x06,0x3E,0x04,0x02,0x9A,0x22,0x06,0x32,0x03,0x02,0xB4,0x26,0x06,0x27,0x07,0x01,0x7D,0x04,0x06,0x2E,0x04,0x01,0x6D,0x22,0x06,0x3A,0x04,0x01,0x6D,0x2F,0x01,0x98,0x11,0x01,0x76,0x1E,0x01,0x84,0x60,0x01,0xA6,0x31,0xFF,0xEE,0x41,0xFD,0x06,0x45,0x0C,0x02,0x96,0x20,0x06,0x36,0x04,0x02,0x99,0x22,0x06,0x2C,0x03,0x02,0xB3,0x2A,0x06,0x23,0x07,0x01,0x7B,0x03,0x06,0x2E,0x04,0x01,0x70,0x23,0x06,0x39,0x04,0x01,0x6C,0x2F,0x01,0xA0,0x0B,0x01,0x74,0x1A,0x01,0x82,0x5A,0x01,0xA3,0x32,0x06,0x3C,0x0B,0x02,0x96,0x20,0x06,0x36,0x04,0x02,0x97,0x23,0x06,0x2C,0x03,0x02,0xB4,0x2B,0x06,0x1F,0x04,0x01,0x77,0x04,0x06,0x29,0x04,0x01,0x6C,0x25,0x06,0x32,0x04,0x01,0x6C,0x2F,0x06,0x26,0x25,0x01,0x74,0x1D,0x01,0x84,0x4C,0x01,0xA3,0x4B,0xFF,0xEE,0x42,0x24,0x06,0x3C,0x0B,0x02,0x96,0x1E,0x06,0x32,0x04,0x02,0x97,0x25,0x06,0x28,0x03,0x02,0xB9,0x2F,0x06,0x1E,0x04,0x01,0x76,0x04,0x06,0x28,0x04,0x01,0x6B,0x26,0x06,0x33,0x04,0x01,0x70,0x2E,0x06,0x1A,0x2F,0x01,0x73,0x21,0x01,0x81,0x35,0x01,0xA5,0x5A,0x06,0x38,0x09,0x02,0x94,0x1D,0x06,0x31,0x04,0x02,0x98,0x26,0x06,0x25,0x03,0x02,0xB6,0x2E,0x06,0x1B,0x04,0x01,0x73,0x07,0x06,0x21,0x04,0x01,0x6A,0x27,0x06,0x2C,0x04,0x01,0x70,0x29,0x06,0x15,0x2F,0x01,0x6F,0x23,0x01,0x7B,0x2E,0x01,0xA4,0x5A,0xFF,0xEE,0x42,0x4D,0x06,0x39,0x08,0x02,0x92,0x1D,0x06,0x2D,0x04,0x02,0x96,0x26,0x06,0x20,0x03,0x02,0xB9,0x2F,0x06,0x1A,0x04,0x01,0x76,0x07,0x06,0x20,0x04,0x01,0x69,0x29,0x06,0x28,0x04,0x01,0x6F,0x23,0x06,0x13,0x2F,0x01,0x74,0x27,0x01,0x7C,0x2B,0x01,0xA7,0x3F,0x06,0x35,0x07,0x02,0x93,0x1C,0x06,0x28,0x04,0x02,0x97,0x26,0x06,0x1B,0x03,0x02,0xB8,0x31,0x06,0x15,0x04,0x01,0x73,0x08,0x06,0x1C,0x04,0x01,0x6C,0x2A,0x06,0x28,0x04,0x01,0x6F,0x21,0x06,0x0E,0x31,0x01,0x70,0x2A,0x01,0x7A,0x2A,0x01,0xA3,0x32,0xFF,0xEE,0x42,0x74,0x06,0x36,0x04,0x02,0x92,0x1A,0x06,0x27,0x04,0x02,0x96,0x23,0x06,0x17,0x03,0x02,0xBA,0x31,0x06,0x18,0x04,0x01,0x76,0x08,0x06,0x1A,0x04,0x01,0x6B,0x2A,0x06,0x25,0x04,0x01,0x6D,0x22,0x06,0x0C,0x21,0x01,0x73,0x2B,0x01,0x7C,0x2A,0x01,0xA2,0x2D,0x06,0x30,0x03,0x02,0x92,0x18,0x06,0x22,0x04,0x02,0x95,0x1C,0x06,0x12,0x04,0x02,0xBB,0x2F,0x06,0x12,0x04,0x01,0x73,0x07,0x06,0x14,0x04,0x01,0x68,0x2B,0x06,0x24,0x04,0x01,0x6C,0x23,0x06,0x08,0x0C,0x01,0x71,0x2E,0x01,0x79,0x2D,0x01,0xA1,0x2A,0xFF,0xEE,0x42,0x9D,0x06,0x30,0x03,0x02,0x93,0x1A,0x06,0x1E,0x04,0x02,0x96,0x15,0x06,0x13,0x03,0x02,0xB9,0x2B,0x06,0x10,0x04,0x01,0x76,0x07,0x06,0x15,0x04,0x01,0x68,0x2A,0x06,0x1F,0x04,0x01,0x6D,0x25,0x06,0x06,0x0B,0x01,0x71,0x2E,0x01,0x78,0x2D,0x01,0xA1,0x2A,0x06,0x2D,0x03,0x02,0x92,0x1D,0x06,0x1A,0x04,0x02,0x9C,0x16,0x06,0x0D,0x04,0x02,0xB8,0x2A,0x06,0x0B,0x04,0x01,0x76,0x04,0x06,0x10,0x04,0x01,0x66,0x2B,0x06,0x1E,0x04,0x01,0x6C,0x27,0x06,0x01,0x0B,0x01,0x71,0x2F,0x01,0x75,0x2B,0x01,0xA0,0x26,0xFF,0xEE,0x42,0xC4,0x06,0x2C,0x04,0x02,0x95,0x1E,0x06,0x1C,0x04,0x02,0x9E,0x14,0x06,0x0B,0x04,0x02,0xBC,0x2B,0x06,0x0A,0x04,0x01,0x76,0x04,0x06,0x0E,0x04,0x01,0x6A,0x2B,0x06,0x18,0x04,0x01,0x68,0x29,0x05,0xFD,0x0B,0x01,0x70,0x2F,0x01,0x75,0x2A,0x01,0x9F,0x22,0x06,0x29,0x03,0x02,0x94,0x1D,0x06,0x18,0x04,0x02,0xA0,0x10,0x06,0x09,0x04,0x02,0xBB,0x2B,0x06,0x04,0x04,0x01,0x78,0x03,0x06,0x09,0x04,0x01,0x69,0x2B,0x06,0x15,0x04,0x01,0x67,0x2B,0x05,0xF9,0x0B,0x01,0x6F,0x2F,0x01,0x76,0x2A,0x01,0x9B,0x23,0xFF,0xEE,0x42,0xED,0x06,0x26,0x04,0x02,0x95,0x1A,0x06,0x14,0x04,0x02,0xA4,0x0C,0x06,0x09,0x04,0x02,0xBC,0x2A,0x06,0x01,0x04,0x01,0x75,0x03,0x06,0x07,0x04,0x01,0x68,0x2A,0x06,0x14,0x04,0x01,0x66,0x2B,0x05,0xF9,0x0B,0x01,0x70,0x2F,0x01,0x78,0x2A,0x01,0x9D,0x25,0x06,0x26,0x04,0x02,0x97,0x19,0x06,0x15,0x04,0x02,0xA0,0x0E,0x06,0x04,0x04,0x02,0xBB,0x29,0x05,0xFE,0x04,0x01,0x73,0x03,0x06,0x01,0x04,0x01,0x68,0x2A,0x06,0x0D,0x04,0x01,0x68,0x2E,0x05,0xF5,0x2D,0x01,0x71,0x2F,0x01,0x71,0x27,0x01,0x9C,0x29,0xFF,0xEE,0x43,0x14,0x06,0x21,0x03,0x02,0x99,0x1C,0x06,0x11,0x04,0x02,0xA1,0x0D,0x06,0x04,0x04,0x02,0xBF,0x26,0x05,0xFF,0x04,0x00,0x00,0x00,0x06,0x03,0x04,0x01,0x69,0x29,0x06,0x0C,0x04,0x01,0x67,0x2E,0x05,0xF6,0x38,0x01,0x70,0x2F,0x01,0x72,0x26,0x01,0x96,0x2A,0x06,0x20,0x03,0x02,0x99,0x1C,0x06,0x0F,0x04,0x02,0xA9,0x0C,0x05,0xFF,0x04,0x02,0xBC,0x29,0x05,0xF7,0x04,0x00,0x00,0x00,0x05,0xFF,0x04,0x01,0x68,0x27,0x06,0x09,0x04,0x01,0x66,0x2E,0x05,0xF3,0x3C,0x01,0x71,0x2F,0x01,0x72,0x27,0x01,0x94,0x2D,0xFF,0xEE,0x43,0x3D,0x06,0x1E,0x03,0x02,0x9B,0x18,0x06,0x08,0x04,0x02,0xAB,0x09,0x05,0xFB,0x04,0x02,0xBD,0x29,0x05,0xF5,0x04,0x01,0x7A,0x03,0x05,0xFE,0x04,0x01,0x6A,0x23,0x06,0x06,0x04,0x01,0x68,0x2E,0x05,0xEF,0x3C,0x01,0x73,0x2F,0x01,0x72,0x27,0x01,0x96,0x31,0x06,0x17,0x04,0x02,0x9E,0x0E,0x06,0x09,0x04,0x06,0xE3,0x01,0x05,0xFB,0x04,0x02,0xC2,0x29,0x05,0xF4,0x07,0x01,0x77,0x03,0x05,0xFB,0x04,0x01,0x6D,0x21,0x05,0xFF,0x04,0x01,0x6B,0x2D,0x05,0xEE,0x3C,0x01,0x74,0x2E,0x01,0x6F,0x25,0x01,0x95,0x31,0xFF,0xEE,0x43,0x64,0x06,0x16,0x03,0x02,0xA1,0x0C,0x06,0x05,0x04,0x06,0xB5,0x02,0x05,0xF5,0x04,0x02,0xC0,0x26,0x05,0xF3,0x04,0x01,0x74,0x03,0x05,0xF6,0x04,0x01,0x6B,0x1C,0x06,0x01,0x04,0x01,0x69,0x2A,0x05,0xEB,0x36,0x01,0x71,0x2B,0x01,0x72,0x2A,0x01,0x91,0x32,0x06,0x11,0x04,0x02,0xA7,0x0B,0x05,0xFE,0x04,0x06,0xB5,0x02,0x05,0xF1,0x04,0x02,0xC3,0x23,0x05,0xED,0x04,0x01,0x74,0x03,0x05,0xF4,0x04,0x01,0x6D,0x16,0x05,0xFC,0x04,0x01,0x6B,0x2A,0x00,0x00,0x00,0x01,0x75,0x2A,0x01,0x70,0x2A,0x01,0x95,0x32,0xFF,0xEE,0x43,0x8D,0x06,0x13,0x04,0x00,0x00,0x00,0x05,0xFE,0x04,0x06,0xB1,0x03,0x05,0xF2,0x04,0x02,0xC2,0x25,0x05,0xF0,0x04,0x01,0x73,0x03,0x05,0xF6,0x04,0x01,0x6F,0x0E,0x05,0xF9,0x04,0x01,0x6B,0x27,0x05,0x85,0x32,0x01,0x72,0x27,0x01,0x6F,0x29,0x01,0x91,0x32,0x06,0x0C,0x04,0x00,0x00,0x00,0x05,0xF9,0x04,0x06,0xB0,0x03,0x05,0xEB,0x04,0x02,0xC4,0x22,0x05,0xEA,0x04,0x01,0x71,0x03,0x05,0xEE,0x04,0x01,0x6F,0x0D,0x05,0xF5,0x04,0x01,0x70,0x27,0x05,0x7D,0x35,0x01,0x76,0x26,0x01,0x6D,0x26,0x01,0x93,0x33,0x00,0x00,0x00,0x00,0x00,0xFF]),
    ]

    public Definitions: UnwrapNestedRefs<Map<string, ProtocolDefinition>> = reactive(ToMap<string, ProtocolDefinition>([
        new ProtocolDefinition(1, 'Header'),
        new ProtocolDefinition(2, 'ProtocoIVersion'),
        new ProtocolDefinition(3, 'MainBoardCount'),
        new ProtocolDefinition(4, 'BaseBoardCount'),
        new ProtocolDefinition(5, 'DistanceRatio'),
        new ProtocolDefinition(6, 'AnglePulseCount'),
        new ProtocolDefinition(7, 'Second'),
        new ProtocolDefinition(8, 'MilliSecond'),
        new ProtocolDefinition(9, 'LidarType'),
        new ProtocolDefinition(10, 'DataBlockHeader'),
        new ProtocolDefinition(11, 'Azimuth'),
        new ProtocolDefinition(12, 'Distance'),
        new ProtocolDefinition(13, 'Reflectivity'),
        new ProtocolDefinition(14, 'Tail'),
    ], element => element.Name));

    public FormattedData: Ref<string> = ref('');
   
    public showReferences = ref(false);
    public showResults = ref(false);

    private watchStopHandles: Array<WatchStopHandle> = [];

    public async Awake(): Promise<void> {
        const lock = await LidarComponent.Default.WaitAsync();

        WebWindowComponent.Default.SetBlackBackground();
        TooltipComponent.Default.Clear();

        lock.Dispose();
    }

    public async Destroy(): Promise<void> {
        const lock = await LidarComponent.Default.WaitAsync();
        this.Type.value = -1;
        lock.Dispose();
    }

    private ParseFrame(data: Uint8Array): ProtocolFrame {
        const frame = new ProtocolFrame();

        const dataView = new DataView(data.buffer, data.byteOffset, data.length);

        frame.ProtocoIVersion = dataView.getUint16(4, false);
        frame.MainBoardCount = dataView.getUint32(8, false);
        frame.BaseBoardCount = dataView.getUint32(12, false);
        frame.DistanceRatio = dataView.getUint8(17) == 1 ? 0.25 : 0.05;
        frame.AnglePulseCount = dataView.getUint16(18, false);
        frame.Second = dataView.getUint32(20,false) * 256 * 256 + dataView.getUint16(24,false);  // 6位
        frame.MilliSecond = dataView.getUint32(26, false);
        frame.LidarType = dataView.getUint8(31);
        frame.Azimuth = dataView.getUint16(44, false) * 0.01;
        frame.Distance = dataView.getUint16(46, false) * frame.DistanceRatio;
        frame.Reflectivity = dataView.getUint8(48)

        return frame;
    }

    public Receive(datas: Array<Uint8Array>): void {
        if (this.DataSource.value == 'Simulate') {
            return;
        }

        const count = this.Datas.length + datas.length - this.Capacity;
        this.Datas.removeAt(0, count);
        this.Datas.addRange(datas);
    }

    private OnDataSourceChanged(): void {
        if (this.DataSource.value == 'Device') {
            this.OnDataSourceChangedToDevice();
        } else {
            this.OnDataSourceChangedToSimulation();
        }
    }

    private OnDataSourceChangedToDevice(): void {
        this.Datas.clear();
    }

    private OnDataSourceChangedToSimulation(): void {
        this.Datas.clear();
        this.Datas.addRange(this.SimulatedData);
        // this.Datas.addRange(this.SimulatedData.filter(data => this.Type.value == 0 || data.Id == this.Type.value));
    }

    public Resolve(data: Uint8Array): void {
        console.log('点击了数据');
        
        this.showReferences.value = false;
        this.showResults.value = false;
        this.Definitions.forEach((item)=>{
            item.Value = ''
          })
        this.DataBits.value.clear();
        this.DataBits.value.addRange(Array.from(data));

        for (const [key, value] of Object.entries(this.ParseFrame(data))) {
            this.Definitions.get(key)!.Reference = value.toString();
        }

        // CAN信号解析
        function ResolveSingalValue(start: number, length: number, data: Array<number>): number {
            let merge = 0;
            let value = 0;

            const lsbBit = start & 7;
            const lsbByte = start >> 3;

            const msbByte = lsbByte - ((lsbBit + length - 1) >> 3);
            for (let index = msbByte; index < lsbByte + 1; index++) {
                merge += data[index] << ((lsbByte - index) << 3);
            }

            value = merge >> lsbBit;
            value = value & ((1 << length) - 1);

            return value;
        }
    }

    /**
     * 当前协议类型发生变化时
     * @param value 模块
     */
    private async OnTypeChangedAsync(value: number, previous: number): Promise<void> {
        this.Datas.clear();
        //@ts-ignore
        const request = new ClientMessage.MillimeterWaveRadarProtocolDataFilterUpdateRequest(LidarSettings.Default.DeviceIndex, value);
        await WebSocketComponent.Default.PostMessageAsync(request);

        if (this.DataSource.value == 'Simulate') {
            this.OnDataSourceChangedToSimulation();
        }
    }

    /**
     * 计算当前二进制Bit
     * @param index 配置索引
     */
    public CalculateBit(index: number): number {
        return index < this.DataBits.value.length ? this.DataBits.value[index] : 0;
    }

    public Convert(input: string, fromRadix: number, toRadix: number): string {
        return input == '' ? '' : Number.parseInt(input, fromRadix).toString(toRadix);
    }
}


/**
 *  应用组件
 */
export class UsageComponent {
    private static instance: UsageComponent = new UsageComponent();
    /**
     * 应用组件
     */
    public static get Default(): UsageComponent {
        return this.instance;
    }

    constructor() {
        window.addEventListener('unload', this.Dispose.bind(this));

        this.watchStopHandles.push(watch(this.RecognitionMode, this.OnRecognitionModeChangedAsync.bind(this)));
    }

    Dispose() {
        window.removeEventListener('unload', this.Dispose);

        for (const watchStopHandle of this.watchStopHandles) {
            watchStopHandle();
        }
        this.watchStopHandles.clear();
    }

    /**
     * 目标识别 true:真实模型 false:Box
     */
    public RecognitionMode: Ref<boolean> = ref(false);

    private watchStopHandles: Array<WatchStopHandle> = [];

    private hasInitialized: boolean = false;
    private usageNode: number = 0;
    private instanceId: number = 0;

    private volume: number = 0;
    private effect: number = 0;

    public async Awake(): Promise<void> {
        const lock = await LidarComponent.Default.WaitAsync();

        WebWindowComponent.Default.SetTransparentBackground();
        TooltipComponent.Default.Clear();

        this.volume = await PostProcessLayerComponent.Default.AddVolumeAsync();
        this.effect = await PostProcessLayerComponent.Default.AddKawaseBlurAsync(this.volume);

        if (!this.hasInitialized) {
            await this.LoadAsync();

            this.hasInitialized = true;
        }

        await OrbitCameraComponent.Default.ChangeTargetAsync(0);

        await UsageCameraComponent.Default.UpdateAsync(this.instanceId, 0.5, 1, 0.5, 300);

        await GameObjectComponent.Default.ShowAsync(this.usageNode);

        await PostProcessLayerComponent.Default.RemoveEffectAsync(this.volume, this.effect);
        await PostProcessLayerComponent.Default.RemoveVolumeAsync(this.volume);

        lock.Dispose();
    }

    public async Destroy(): Promise<void> {
        const lock = await LidarComponent.Default.WaitAsync();

        await GameObjectComponent.Default.HideAsync(this.usageNode);

        await UsageCameraComponent.Default.ChangeTargetAsync(0);

        lock.Dispose();

        lock.Dispose();
    }

    private async LoadAsync(): Promise<void> {
        this.instanceId = await AssetLoaderComponent.Default.LoadAsync('Assets/R00062/ICV/Res/Product/Apply/激光雷达系统/激光雷达系统.prefab');
        this.usageNode = await GameObjectComponent.Default.FindAsync('[UsageNode]');
        await GameObjectComponent.Default.SetParentAsync(this.instanceId, this.usageNode);
    }

    /**
     * 当目标识别模式发生改变
     * @param mode 识别模式
     */
    private async OnRecognitionModeChangedAsync(mode: boolean): Promise<void> {
        await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.MillimeterWaveRadarRecognitionModeRequest(mode));
    }

    public async OnNavigateToChildAsync(value: string): Promise<void> {
        this.volume = await PostProcessLayerComponent.Default.AddVolumeAsync();
        this.effect = await PostProcessLayerComponent.Default.AddKawaseBlurAsync(this.volume);

        await RouterComponent.Default.NavigateToChildAsync(value);
    }

    public async NavigateToPreviousAsync(): Promise<void> {
        RouterComponent.Default.NavigateToPrevious();

        await PostProcessLayerComponent.Default.RemoveEffectAsync(this.volume, this.effect);
        await PostProcessLayerComponent.Default.RemoveVolumeAsync(this.volume);
    }
}

/**
 * 基本信息组件
 */
export class BaseInformationComponent {
    private static instance: BaseInformationComponent = new BaseInformationComponent();
    /**
     * 基本信息组件
     */
    public static get Default(): BaseInformationComponent {
        return this.instance;
    }

    constructor() {
        window.addEventListener('unload', this.Dispose.bind(this));
    }

    Dispose() {
        window.removeEventListener('unload', this.Dispose);
    }

    /**
     * 设置毫米波雷达基本配置
     * @param configuration 毫米波雷达基本配置
     */
    public async UpdateAsync(configuration: ClientMessage.MillimeterWaveRadarBaseConfiguration): Promise<void> {
        const deviceId = LidarSettings.Default.DeviceIndex;
        configuration.MaxDistance /= 2;
        configuration.MaxDistance |= 0;
        await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.MillimeterWaveRadarBaseConfigurationUpdateRequest(deviceId, configuration));
    }

    /**
     * 重置毫米波雷达基本配置
     */
    public async ResetAsync(): Promise<void> {
        const deviceId = LidarSettings.Default.DeviceIndex;
        const configuration = new ClientMessage.MillimeterWaveRadarBaseConfiguration(
            true, true, true, true, true, true, true, true, true, true,
            true, 0, 1, 200 / 2, 0, false, false, false, 0, false
        );
        await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.MillimeterWaveRadarBaseConfigurationUpdateRequest(deviceId, configuration));
    }
}

/**
 * 物体信息组件
 */
export class ObjectInformationComponent {
    private static instance: ObjectInformationComponent = new ObjectInformationComponent();
    /**
     * 物体信息组件
     */
    public static get Default(): ObjectInformationComponent {
        return this.instance;
    }

    constructor() {
        window.addEventListener('unload', this.Dispose.bind(this));

        this.watchStopHandles.push(watch(this.Visibility, this.UpdateVisibilityAsync.bind(this)));
        this.watchStopHandles.push(watch(this.VisibleFields, this.UpdateVisibleFieldsAsync.bind(this)));
    }

    Dispose() {
        window.removeEventListener('unload', this.Dispose);

        for (const watchStopHandle of this.watchStopHandles) {
            watchStopHandle();
        }
        this.watchStopHandles.clear();
    }

    /**
     * 可见性
     */
    public Visibility: Ref<boolean> = ref(false);

    /**
     * 可见字段
     */
    public VisibleFields: Ref<Array<string>> = ref([]);

    /**
     * Vue Watches
     */
    private watchStopHandles: Array<WatchStopHandle> = new Array<WatchStopHandle>();

    /**
     * 更新可见性
     * @param visibility 可见性
     * @returns 操作是否成功
     */
    private async UpdateVisibilityAsync(visibility: boolean): Promise<boolean> {
        const response = await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.MillimeterWaveRadarObjectInformationVisibilityUpdateRequest(visibility));
        return response.Error == 0;
    }

    /**
     * 更新可见字段
     * @param fields 可见字段
     * @returns 操作是否成功
     */
    private async UpdateVisibleFieldsAsync(fields: Array<string>): Promise<boolean> {
        const response = await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.MillimeterWaveRadarObjectInformationVisibleFieldsUpdateRequest(fields));
        return response.Error == 0;
    }
}

/**
 * 过滤器配置
 */
class FilterConfig {
    Id: number;
    Name: string;
    Active: boolean = false;
    State: string;
    Min: string;
    Max: string;
    Offset: number;
    Step: string;
    Precision: string;
    Range: Array<string>;
    Options: Array<string>;

    constructor(id: number, name: string, active: boolean = false, state: string = '', min: string = '', max: string = '', offset: number = 0, step: string = '', precision: string = '1', range: Array<string> = [], options: Array<string> = []) {
        this.Id = id;
        this.Name = name;
        this.Active = active;
        this.State = state;
        this.Min = min;
        this.Max = max;
        this.Offset = offset;
        this.Step = step;
        this.Precision = precision;
        this.Range = range;
        this.Options = options;
    }
}

/**
 * 毫米波雷达过滤器组件
 */
export class FilterComponent {
    private static instance: FilterComponent = new FilterComponent();
    /**
     * 毫米波雷达过滤器组件
     */
    public static get Default(): FilterComponent {
        return this.instance;
    }

    constructor() {
        window.addEventListener('unload', this.Dispose.bind(this));
    }

    Dispose() {
        window.removeEventListener('unload', this.Dispose);
    }

    /**
     * 所有过滤器默认配置
     */
    public AllDefinition: Array<FilterConfig> = [
        new FilterConfig(0x0, '输出目标数量(个)', false, '', '0', '100', 0, '1', '1', ['0', '250']),
        new FilterConfig(0x1, '径向距离(m)', false, '', '0.0', '100.0', 0, '0.1', '0.1', ['0.0', '409.5']),
        new FilterConfig(0x2, '水平角度(°)', false, '', '-50.00', '50.00', 50, '0.05', '0.025', ['-50.00', '52.37']),
        new FilterConfig(0x3, '径向来向速度(m/s)', false, '', '0.00', '20.00', 0, '0.05', '0.0315', ['-50.00', '128.99']),
        new FilterConfig(0x4, '径向去向速度(m/s)', false, '', '0.00', '20.00', 0, '0.05', '0.0315', ['-50.00', '128.99']),
        new FilterConfig(0x5, '雷达反射截面积去向速度(m/s)', false, '', '-10.00', '10.00', 50, '0.05', '0.025', ['-50.00', '52.37']),
        new FilterConfig(0x6, '目标持续时间(s)', false, '', '0.0', '20.0', 0, '0.1', '0.1', ['0.0', '409.5']),
        new FilterConfig(0x7, '目标大小(m2)', false, '', '0.00', '20.00', 0, '0.05', '0.025', ['0.00', '102.37']),
        new FilterConfig(0x8, '存在可能性(%)', false, '', '0: 0%', '7: 100%', 0, '', '1', [], ['0: 0%', '1: 25%', '2: 50%', '3: 75%', '4: 90%', '5: 99%', '6: 99.9%', '7: 100%']),
        new FilterConfig(0x9, 'Y方向距离(m)', false, '', '-100.0', '100.0', 409.5, '0.1', '0.2', ['-409.5', '409.5']),
        new FilterConfig(0xA, 'X方向距离(m)', false, '', '0', '100', 500, '0.2', '0.2', ['-500', '1138.2']),
        new FilterConfig(0xB, '从右向左分速度(m/s)', false, '', '0.00', '20.00', 0, '0.05', '0.0315', ['0.00', '128.99']),
        new FilterConfig(0xC, '从左向右分速度(m/s)', false, '', '0.00', '20.00', 0, '0.05', '0.0315', ['0.00', '128.99']),
        new FilterConfig(0xD, '来向分速度(m/s)', false, '', '0.00', '20.00', 0, '0.05', '0.0315', ['0.00', '128.99']),
        new FilterConfig(0xE, '去向分速度(m/s)', false, '', '0.00', '20.00', 0, '0.05', '0.0315', ['0.00', '128.99']),
    ];

    /**
     * 所有过滤器配置
     */
    public AllConfiguration: UnwrapNestedRefs<Array<FilterConfig>> = reactive([
        new FilterConfig(0x0, '输出目标数量(个)', false, '', '0', '100', 0, '1', '1', ['0', '250']),
        new FilterConfig(0x1, '径向距离(m)', false, '', '0.0', '100.0', 0, '0.1', '0.1', ['0.0', '409.5']),
        new FilterConfig(0x2, '水平角度(°)', false, '', '-50.00', '50.00', 50, '0.05', '0.025', ['-50.00', '52.37']),
        new FilterConfig(0x3, '径向来向速度(m/s)', false, '', '0.00', '20.00', 0, '0.05', '0.0315', ['-50.00', '128.99']),
        new FilterConfig(0x4, '径向去向速度(m/s)', false, '', '0.00', '20.00', 0, '0.05', '0.0315', ['-50.00', '128.99']),
        new FilterConfig(0x5, '雷达反射截面积去向速度(m/s)', false, '', '-10.00', '10.00', 50, '0.05', '0.025', ['-50.00', '52.37']),
        new FilterConfig(0x6, '目标持续时间(s)', false, '', '0.0', '20.0', 0, '0.1', '0.1', ['0.0', '409.5']),
        new FilterConfig(0x7, '目标大小(m2)', false, '', '0.00', '20.00', 0, '0.05', '0.025', ['0.00', '102.37']),
        new FilterConfig(0x8, '存在可能性(%)', false, '', '0: 0%', '7: 100%', 0, '', '1', [], ['0: 0%', '1: 25%', '2: 50%', '3: 75%', '4: 90%', '5: 99%', '6: 99.9%', '7: 100%']),
        new FilterConfig(0x9, 'Y方向距离(m)', false, '', '-100.0', '100.0', 409.5, '0.1', '0.2', ['-409.5', '409.5']),
        new FilterConfig(0xA, 'X方向距离(m)', false, '', '0', '100', 500, '0.2', '0.2', ['-500', '1138.2']),
        new FilterConfig(0xB, '从右向左分速度(m/s)', false, '', '0.00', '20.00', 0, '0.05', '0.0315', ['0.00', '128.99']),
        new FilterConfig(0xC, '从左向右分速度(m/s)', false, '', '0.00', '20.00', 0, '0.05', '0.0315', ['0.00', '128.99']),
        new FilterConfig(0xD, '来向分速度(m/s)', false, '', '0.00', '20.00', 0, '0.05', '0.0315', ['0.00', '128.99']),
        new FilterConfig(0xE, '去向分速度(m/s)', false, '', '0.00', '20.00', 0, '0.05', '0.0315', ['0.00', '128.99']),
    ]);

    /**
     * 所有过滤器信息
     */
    public AllInformation: UnwrapNestedRefs<Array<FilterConfig>> = reactive([
        new FilterConfig(0x0, '输出目标数量(个)', false, '', '', ''),
        new FilterConfig(0x1, '径向距离(m)', false, '', '', ''),
        new FilterConfig(0x2, '水平角度(°)', false, '', '', ''),
        new FilterConfig(0x3, '径向来向速度(m/s)', false, '', '', ''),
        new FilterConfig(0x4, '径向去向速度(m/s)', false, '', '', ''),
        new FilterConfig(0x5, '雷达反射截面积去向速度(m/s)', false, '', '', ''),
        new FilterConfig(0x6, '目标持续时间(s)', false, '', '', ''),
        new FilterConfig(0x7, '目标大小(m2)', false, '', '', ''),
        new FilterConfig(0x8, '存在可能性(%)', false, '', '', ''),
        new FilterConfig(0x9, 'Y方向距离(m)', false, '', '', ''),
        new FilterConfig(0xA, 'X方向距离(m)', false, '', '', ''),
        new FilterConfig(0xB, '从右向左分速度(m/s)', false, '', '', ''),
        new FilterConfig(0xC, '从左向右分速度(m/s)', false, '', '', ''),
        new FilterConfig(0xD, '来向分速度(m/s)', false, '', '', ''),
        new FilterConfig(0xE, '去向分速度(m/s)', false, '', '', ''),
    ]);

    /**
     * 设置过滤器
     * @param id 过滤器Id
     * @returns 设置是否成功
     */
    public async SetFilterAsync(id: number): Promise<boolean> {
        const configuration = this.AllConfiguration.find(configuration => configuration.Id == id)!;
        const deviceId = LidarSettings.Default.DeviceIndex;
        const type = LidarSettings.Default.BaseInformation.OutputTypeCfg == 'Objects';
        const min = Number.parseInt(`${(Number.parseFloat(configuration.Min) + configuration.Offset) * 10000 / (Number.parseFloat(configuration.Precision) * 10000)}`);
        const max = Number.parseInt(`${(Number.parseFloat(configuration.Max) + configuration.Offset) * 10000 / (Number.parseFloat(configuration.Precision) * 10000)}`);
        const request = new ClientMessage.MillimeterWaveRadarFilterConfigurationUpdateRequest(deviceId,
            [new ClientMessage.MillimeterWaveRadarFilterConfiguration(true, configuration.Active, type, id, min, max)]);
        const response = await WebSocketComponent.Default.PostMessageAsync(request);
        return response.Error == 0;
    }

    /**
     * 查询所有过滤器信息
     * @returns 操作是否成功
     */
    public async QueryAsync(): Promise<boolean> {
        const deviceId = LidarSettings.Default.DeviceIndex;
        const request = new ClientMessage.MillimeterWaveRadarFilterConfigurationUpdateRequest(deviceId,
            this.AllDefinition.map(definition => this.ComputeFilterConfiguration(definition)));
        const response = await WebSocketComponent.Default.PostMessageAsync(request);
        return response.Error == 0;
    }

    /**
     * 计算过滤器对应的默认设置
     * @param definition 过滤器定义
     * @returns 
     */
    private ComputeFilterConfiguration(definition: FilterConfig): ClientMessage.MillimeterWaveRadarFilterConfiguration {
        const type = LidarSettings.Default.BaseInformation.OutputTypeCfg == 'Objects';
        const min = Number.parseInt(`${(Number.parseFloat(definition.Min) + definition.Offset) * 10000 / (Number.parseFloat(definition.Precision) * 10000)}`);
        const max = Number.parseInt(`${(Number.parseFloat(definition.Max) + definition.Offset) * 10000 / (Number.parseFloat(definition.Precision) * 10000)}`);
        return new ClientMessage.MillimeterWaveRadarFilterConfiguration(true, true, type, definition.Id, min, max);
    }

    /**
     * 更新所有过滤器信息
     * @param informations 过滤器信息
     */
    public UpdateInformations(informations: Array<ClientMessage.MillimeterWaveRadarFilterInformation>): void {
        for (const information of informations) {
            this.UpdateFilterInformation(information);
        }
    }

    /**
     * 更新对应的过滤器信息
     * @param input 过滤器信息
     */
    private UpdateFilterInformation(input: ClientMessage.MillimeterWaveRadarFilterInformation): void {
        const information = this.AllInformation.find(information => information.Id == input.Index)!;
        information.State = input.Active;
        information.Min = input.Min;
        information.Max = input.Max;
    }
}

/**
 * 碰撞检测组件
 */
export class CollisionComponent {
    private static instance: CollisionComponent = new CollisionComponent();
    /**
     * 碰撞检测组件
     */
    public static get Default(): CollisionComponent {
        return this.instance;
    }

    constructor() {
        window.addEventListener('unload', this.Dispose.bind(this));
    }

    Dispose() {
        window.removeEventListener('unload', this.Dispose);
    }

    /**
     * 设置毫米波雷达碰撞检测配置
     * @param resetWarning 报警信息重置
     * @param activation 是否使能配置
     * @param clearRegions 清除所有区域
     * @param minTimeValid 最短时间是否生效
     * @param minTime 最短时间
     * @returns 
     */
    public async SetCollisionAsync(resetWarning: boolean, activation: boolean, clearRegions: boolean, minTimeValid: boolean, minTime: number): Promise<boolean> {
        const deviceId = LidarSettings.Default.DeviceIndex;

        minTime *= 10;
        minTime |= 0;

        const configuration = new ClientMessage.MillimeterWaveRadarCollisionConfiguration(resetWarning, activation, clearRegions, minTimeValid, minTime);
        const request = new ClientMessage.MillimeterWaveRadarCollisionConfigurationUpdateRequest(deviceId, configuration);
        const response = await WebSocketComponent.Default.PostMessageAsync(request);
        return response.Error == 0;
    }

    /**
     * 设置碰撞检测区域配置
     * @param activation 是否使能配置
     * @param coordinatesValid 坐标是否有效
     * @param regionID 区域Id
     * @param point1X P1 X坐标
     * @param point1Y P1 Y坐标
     * @param point2X P2 X坐标
     * @param point2Y P2 Y坐标
     * @returns 
     */
    public async SetCollisionRegionAsync(activation: boolean, coordinatesValid: boolean, regionID: number, point1X: string, point1Y: string, point2X: string, point2Y: string): Promise<boolean> {
        const deviceId = LidarSettings.Default.DeviceIndex;

        point1X = `${((Number.parseFloat(point1X) + 500) / 0.2) | 0}`;
        point1Y = `${((Number.parseFloat(point1Y) + 204.6) / 0.2) | 0}`;
        point2X = `${((Number.parseFloat(point2X) + 500) / 0.2) | 0}`;
        point2Y = `${((Number.parseFloat(point2Y) + 204.6) / 0.2) | 0}`;

        const configuration = new ClientMessage.MillimeterWaveRadarCollisionRegionConfiguration(activation, coordinatesValid, regionID, point1X, point1Y, point2X, point2Y);
        const request = new ClientMessage.MillimeterWaveRadarCollisionRegionConfigurationUpdateRequest(deviceId, configuration);
        const response = await WebSocketComponent.Default.PostMessageAsync(request);
        return response.Error == 0;
    }
}

/**
 * 车速组件
 */
export class SpeedComponent {
    private static instance: SpeedComponent = new SpeedComponent();
    /**
     * 车速组件
     */
    public static get Default(): SpeedComponent {
        return this.instance;
    }

    constructor() {
        window.addEventListener('unload', this.Dispose.bind(this));
    }

    Dispose() {
        window.removeEventListener('unload', this.Dispose);
    }

    /**
     * 设置速度
     * @param direction 方向
     * @param speed 速度
     * @returns 
     */
    public async SetSpeedAsync(direction: number, speed: number): Promise<boolean> {
        const deviceId = LidarSettings.Default.DeviceIndex;

        speed *= 50;
        speed |= 0;

        const configuration = new ClientMessage.MillimeterWaveRadarSpeedConfiguration(direction, speed);
        const request = new ClientMessage.MillimeterWaveRadarSpeedUpdateRequest(deviceId, configuration);
        const response = await WebSocketComponent.Default.PostMessageAsync(request);
        return response.Error == 0;
    }
}

/**
 * 横摆角速度组件
 */
export class RateComponent {
    private static instance: RateComponent = new RateComponent();
    /**
     * 横摆角速度组件
     */
    public static get Default(): RateComponent {
        return this.instance;
    }

    constructor() {
        window.addEventListener('unload', this.Dispose.bind(this));
    }

    Dispose() {
        window.removeEventListener('unload', this.Dispose);
    }

    /**
    * 设置速度
    * @param speed 速度
    * @returns 
    */
    public async SetRateAsync(speed: number): Promise<boolean> {
        const deviceId = LidarSettings.Default.DeviceIndex;

        speed = (speed + + 327.68) * 100;
        speed |= 0;

        const configuration = new ClientMessage.MillimeterWaveRadarRateConfiguration(speed);
        const request = new ClientMessage.MillimeterWaveRadarRateUpdateRequest(deviceId, configuration);
        const response = await WebSocketComponent.Default.PostMessageAsync(request);
        return response.Error == 0;
    }
}

/**
 * 碰撞区域可见性组件
 */
export class CollisionRegionVisibilityComponent {
    private static instance: CollisionRegionVisibilityComponent = new CollisionRegionVisibilityComponent();
    /**
     * 碰撞区域可见性组件
     */
    public static get Default(): CollisionRegionVisibilityComponent {
        return this.instance;
    }

    constructor() {
        window.addEventListener('unload', this.Dispose.bind(this));
    }

    Dispose() {
        window.removeEventListener('unload', this.Dispose);
    }

    /**
    * 更新可见性
    * @param state 可见性
    * @returns 
    */
    public async UpdateAsync(state: boolean): Promise<boolean> {
        const deviceId = LidarSettings.Default.DeviceIndex;
        const request = new ClientMessage.MillimeterWaveRadarCollisionRegionVisibilityUpdateRequest(deviceId, state);
        const response = await WebSocketComponent.Default.PostMessageAsync(request);
        return response.Error == 0;
    }
}

/**
 * 检测区域可见性组件
 */
export class DetectionAreaVisibilityComponent {
    private static instance: DetectionAreaVisibilityComponent = new DetectionAreaVisibilityComponent();
    /**
     * 检测区域可见性组件
     */
    public static get Default(): DetectionAreaVisibilityComponent {
        return this.instance;
    }

    constructor() {
        window.addEventListener('unload', this.Dispose.bind(this));
    }

    Dispose() {
        window.removeEventListener('unload', this.Dispose);
    }

    /**
    * 更新可见性
    * @param state 可见性
    * @returns 
    */
    public async UpdateAsync(state: boolean): Promise<boolean> {
        const deviceId = LidarSettings.Default.DeviceIndex;
        const request = new ClientMessage.MillimeterWaveRadarDetectionAreaVisibilityUpdateRequest(deviceId, state);
        const response = await WebSocketComponent.Default.PostMessageAsync(request);
        return response.Error == 0;
    }
}



// 激光雷达=================================================================================
/**
 * 应用界面
 */
export class UseComponent {
    private static instance: UseComponent = new UseComponent();
    /**
     * 应用界面
     */
    public static get Default(): UseComponent {
        return this.instance;
    }
    public deviceState = ref('')
    constructor() {
        window.addEventListener('unload', this.Dispose.bind(this));

        this.watchStopHandles.push(watch(this.Choice, this.OnChoicesChangedAsync.bind(this)));
        // this.watchStopHandles.push(watch(this.ShowScene, this.UpdateMapBuildingSettingsAsync.bind(this)));
        // this.watchStopHandles.push(watch(this.ShowPath, this.UpdateMapBuildingSettingsAsync.bind(this)));
        // this.watchStopHandles.push(watch(this.ShowMap, this.UpdateMapBuildingSettingsAsync.bind(this)));
    }

    Dispose() {
        window.removeEventListener('unload', this.Dispose);

        for (const watchStopHandle of this.watchStopHandles) {
            watchStopHandle();
        }
        this.watchStopHandles.clear();
    }

    // public Options: Map<string, string> = new Map([
    //     ['点云呈现', 'ic_dianyunchengxian'],
    //     ['激光扫描', 'ic_jiguangsaomiao'],
    //     ['地图构建', 'ic_ditugoujian'],
    // ]);
    // public Choice: Ref<string> = ref('点云呈现');
    
    public Options: Ref<Array<string>> = ref(['点云呈现', '激光扫描','地图构建']);
    public Choice: Ref<string> = ref('');

    public ShowScene: Ref<boolean> = ref(true);
    public ShowPath: Ref<boolean> = ref(false);
    public ShowMap: Ref<boolean> = ref(true);

    private watchStopHandles: Array<WatchStopHandle> = [];

    private volume: number = 0;
    private effect: number = 0;

    public async Awake(): Promise<void> {
        const lock = await LidarComponent.Default.WaitAsync();
        WebWindowComponent.Default.SetTransparentBackground();
        await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.LaserRadarUsageTypeRequest(this.Choice.value));
        
        this.Options.value.splice(0, this.Options.value.length);
        // if (response.Error == 0) {
        // if (UseComponent.Default.deviceState.value == '设备连接成功') {
        if (LidarComponent.Default.connect.value == '设备连接成功') {
            this.Options.value.push('点云呈现');
            this.Options.value.push('激光扫描');
            this.Options.value.push('地图构建');

            this.Choice.value = '点云呈现';
            await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.LaserRadarScanSettingsRequest(0,360,300,0.1));
        } else {
            this.Options.value.push('激光扫描');
            this.Options.value.push('地图构建');

            if (this.Choice.value != '激光扫描') {
                this.Choice.value = '激光扫描';
            } else {
                await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.LaserRadarScanSettingsRequest(0,360,300,0.1));
            }

            this.Choice.value = '激光扫描';
        }

        lock.Dispose();
    }

    public async Destroy(): Promise<void> {
        const lock = await LidarComponent.Default.WaitAsync();

        await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.LaserRadarUsageTypeRequest(''));

        lock.Dispose();
    }

    public timer: Ref<any> = ref(null);
    public duration: Ref<number> = ref(0);
    public async OnChoicesChangedAsync(): Promise<void> {
        await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.LaserRadarUsageTypeRequest(this.Choice.value));
        if(this.Choice.value != '地图构建') {
            await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.LaserRadarMapBuildingResetRequest());
            clearInterval(this.timer.value)
            this.timer.value = null 
            UseComponent.Default.ShowScene.value = true
            UseComponent.Default.ShowPath.value = false
            UseComponent.Default.ShowMap.value = true
            await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.LaserRadarMapBuildingSceneRequest(true));
            await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.LaserRadarMapBuildingPathRequest(false));
            await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.LaserRadarMapBuildingMapRequest(true));
            this.duration.value = 0
         }
    }

    public async StartBuildMapAsync(): Promise<boolean> {
        const response = await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.LaserRadarStartBuildMapRequest());        
        return response.Error == 0;
    }

    public async StopBuildMapAsync(): Promise<boolean> {
        const response = await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.LaserRadarStopBuildMapRequest());
        return response.Error == 0;
    }

    // public async UpdateMapBuildingSettingsAsync(): Promise<boolean> {
    //     const response = await WebSocketComponent.Default.PostMessageAsync(new ClientMessage.LaserRadarMapBuildingSettingsRequest(this.ShowScene.value, this.ShowPath.value, this.ShowMap.value));
    //     return response.Error == 0;
    // }
}